// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// clang-format off
#include "src/ui/lib/glm_workaround/glm_workaround.h"
// clang-format on

#include <fuchsia/ui/gfx/cpp/fidl.h>
#include <fuchsia/ui/policy/cpp/fidl.h>
#include <fuchsia/ui/scenic/cpp/fidl.h>
#include <fuchsia/ui/views/cpp/fidl.h>
#include <glm/gtx/quaternion.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/string_cast.hpp>
#include <gtest/gtest.h>
#include <lib/async/cpp/task.h>
#include <lib/fsl/vmo/vector.h>
#include <lib/sys/cpp/testing/test_with_environment.h>
#include <lib/ui/scenic/cpp/session.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>
#include <lib/images/cpp/images.h>
#include <src/lib/fxl/logging.h>
#include <zircon/status.h>

#include <map>
#include <string>
#include <vector>

#include "garnet/lib/ui/gfx/tests/vk_session_test.h"
#include "garnet/testing/views/background_view.h"
#include "garnet/testing/views/coordinate_test_view.h"
#include "garnet/testing/views/opacity_view.h"
#include "garnet/testing/views/test_view.h"
#include "src/ui/lib/escher/impl/vulkan_utils.h"
#include "src/ui/lib/escher/hmd/pose_buffer.h"
#include "src/ui/lib/escher/test/gtest_vulkan.h"
#include "garnet/lib/ui/yuv/yuv.h"

namespace {

constexpr char kEnvironment[] = "ScenicPixelTest";
constexpr zx::duration kTimeout = zx::sec(15);
// If you change the size of YUV buffers, make sure that the YUV test in
// host_image_unittest.cc is also updated. Unlike that unit test,
// scenic_pixel_test.cc has no way to confirm that it is going through the
// direct-to-GPU path.
// TODO(SCN-1387): This number needs to be queried via sysmem or vulkan.
constexpr uint32_t kYuvSize = 64;

// These tests need Scenic and RootPresenter at minimum, which expand to the
// dependencies below. Using |TestWithEnvironment|, we use
// |fuchsia.sys.Environment| and |fuchsia.sys.Loader| from the system (declared
// in our *.cmx sandbox) and launch these other services in the environment we
// create in our test fixture.
//
// Another way to do this would be to whitelist these services in our sandbox
// and inject/start them via the |fuchsia.test| facet. However that has the
// disadvantage that it uses one instance of those services across all tests in
// the binary, making each test not hermetic wrt. the others. A trade-off is
// that the |TestWithEnvironment| method is more verbose.
const std::map<std::string, std::string> kServices = {
    {"fuchsia.tracelink.Registry",
     "fuchsia-pkg://fuchsia.com/trace_manager#meta/trace_manager.cmx"},
    {"fuchsia.ui.policy.Presenter",
     "fuchsia-pkg://fuchsia.com/root_presenter#meta/root_presenter.cmx"},
    {"fuchsia.ui.scenic.Scenic",
     "fuchsia-pkg://fuchsia.com/scenic#meta/scenic.cmx"},
    {"fuchsia.vulkan.loader.Loader",
     "fuchsia-pkg://fuchsia.com/vulkan_loader#meta/vulkan_loader.cmx"},
    {"fuchsia.sysmem.Allocator",
     "fuchsia-pkg://fuchsia.com/sysmem_connector#meta/sysmem_connector.cmx"}};

// Test fixture that sets up an environment suitable for Scenic pixel tests
// and provides related utilities. The environment includes Scenic and
// RootPresenter, and their dependencies.
class ScenicPixelTest : public sys::testing::TestWithEnvironment {
 protected:
  ScenicPixelTest() {
    std::unique_ptr<sys::testing::EnvironmentServices> services =
        CreateServices();

    for (const auto& entry : kServices) {
      fuchsia::sys::LaunchInfo launch_info;
      launch_info.url = entry.second;
      services->AddServiceWithLaunchInfo(std::move(launch_info), entry.first);
    }

    environment_ =
        CreateNewEnclosingEnvironment(kEnvironment, std::move(services));

    environment_->ConnectToService(scenic_.NewRequest());
    scenic_.set_error_handler([](zx_status_t status) {
      FAIL() << "Lost connection to Scenic: " << zx_status_get_string(status);
    });
  }

  // Blocking wrapper around |Scenic::TakeScreenshot|. This should not be called
  // from within a loop |Run|, as it spins up its own to block and nested loops
  // are undefined behavior.
  fuchsia::ui::scenic::ScreenshotData TakeScreenshot() {
    fuchsia::ui::scenic::ScreenshotData screenshot_out;
    scenic_->TakeScreenshot(
        [this, &screenshot_out](fuchsia::ui::scenic::ScreenshotData screenshot,
                                bool status) {
          EXPECT_TRUE(status) << "Failed to take screenshot";
          screenshot_out = std::move(screenshot);
          QuitLoop();
        });
    EXPECT_FALSE(RunLoopWithTimeout(kTimeout))
        << "Timed out waiting for screenshot.";
    return screenshot_out;
  }

  // Create a |ViewContext| that allows us to present a view via
  // |RootPresenter|. See also examples/ui/hello_base_view
  scenic::ViewContext CreatePresentationContext() {
    auto [view_token, view_holder_token] = scenic::ViewTokenPair::New();

    scenic::ViewContext view_context = {
        .session_and_listener_request =
            scenic::CreateScenicSessionPtrAndListenerRequest(scenic_.get()),
        .view_token = std::move(view_token),
    };

    fuchsia::ui::policy::PresenterPtr presenter;
    environment_->ConnectToService(presenter.NewRequest());
    presenter->PresentView(std::move(view_holder_token), nullptr);

    return view_context;
  }

  // Runs until the view renders its next frame. Technically, waits until the
  // |Present| callback is invoked with an expected presentation timestamp, and
  // then waits until that time.
  void RunUntilPresent(scenic::TestView* view) {
    // Typical sequence of events:
    // 1. We set up a view bound as a |SessionListener|.
    // 2. The view sends its initial |Present| to get itself connected, without
    //    a callback.
    // 3. We call |RunUntilPresent| which sets a present callback on our
    //    |TestView|.
    // 4. |RunUntilPresent| runs the message loop, which allows the view to
    //    receive a Scenic event telling us our metrics.
    // 5. In response, the view sets up the scene graph with the test scene.
    // 6. The view calls |Present| with the callback set in |RunUntilPresent|.
    // 7. The still-running message loop eventually dispatches the present
    //    callback.
    // 8. The callback schedules a quit for the presentation timestamp we got.
    // 9. The message loop eventually dispatches the quit and exits.

    bool present_received = false;
    view->set_present_callback(
        [&present_received](fuchsia::images::PresentationInfo info) {
          present_received = true;
        });

    ASSERT_TRUE(RunLoopWithTimeoutOrUntil(
        [&present_received] { return present_received; }, zx::sec(10)));
  }

  fuchsia::ui::scenic::ScenicPtr scenic_;

 private:
  std::unique_ptr<sys::testing::EnclosingEnvironment> environment_;
};

TEST_F(ScenicPixelTest, SolidColor) {
  scenic::BackgroundView view(CreatePresentationContext());
  RunUntilPresent(&view);

  fuchsia::ui::scenic::ScreenshotData screenshot = TakeScreenshot();

  EXPECT_GT(screenshot.info.width, 0u);
  EXPECT_GT(screenshot.info.height, 0u);

  // We could assert on each pixel individually, but a histogram might give us a
  // more meaningful failure.
  std::map<scenic::Color, size_t> histogram = scenic::Histogram(screenshot);

  EXPECT_GT(histogram[scenic::BackgroundView::kBackgroundColor], 0u);
  histogram.erase(scenic::BackgroundView::kBackgroundColor);
  // This assert is written this way so that, when it fails, it prints out all
  // the unexpected colors
  EXPECT_EQ((std::map<scenic::Color, size_t>){}, histogram)
      << "Unexpected colors";
}

TEST_F(ScenicPixelTest, NV12Texture) {
  scenic::BackgroundView view(CreatePresentationContext());
  fuchsia::images::ImageInfo image_info{
      .width = kYuvSize,
      .height = kYuvSize,
      .stride = static_cast<uint32_t>(
          kYuvSize *
          images::StrideBytesPerWidthPixel(fuchsia::images::PixelFormat::NV12)),
      .pixel_format = fuchsia::images::PixelFormat::NV12,
  };

  uint32_t num_pixels = image_info.width * image_info.height;
  uint64_t image_vmo_bytes = images::ImageSize(image_info);
  EXPECT_EQ((3 * num_pixels) / 2, image_vmo_bytes);

  zx::vmo image_vmo;
  zx_status_t status = zx::vmo::create(image_vmo_bytes, 0, &image_vmo);
  EXPECT_EQ(ZX_OK, status);
  uint8_t* vmo_base;
  status = zx::vmar::root_self()->map(0, image_vmo, 0, image_vmo_bytes,
                                      ZX_VM_PERM_WRITE | ZX_VM_PERM_READ,
                                      reinterpret_cast<uintptr_t*>(&vmo_base));
  EXPECT_EQ(ZX_OK, status);

  static const uint8_t kYValue = 110;
  static const uint8_t kUValue = 192;
  static const uint8_t kVValue = 192;

  // Set all the Y pixels at full res.
  for (uint32_t i = 0; i < num_pixels; ++i) {
    vmo_base[i] = kYValue;
  }

  // Set all the UV pixels pairwise at half res.
  for (uint32_t i = num_pixels; i < num_pixels + num_pixels / 2; i += 2) {
    vmo_base[i] = kUValue;
    vmo_base[i + 1] = kVValue;
  }

  view.SetHostImage(std::move(image_vmo), image_vmo_bytes, image_info);
  RunUntilPresent(&view);

  fuchsia::ui::scenic::ScreenshotData screenshot = TakeScreenshot();

  EXPECT_GT(screenshot.info.width, 0u);
  EXPECT_GT(screenshot.info.height, 0u);

  // We could assert on each pixel individually, but a histogram might give us a
  // more meaningful failure.
  std::map<scenic::Color, size_t> histogram = scenic::Histogram(screenshot);

  uint8_t bgra[4];
  yuv::YuvToBgra(kYValue, kUValue, kVValue, bgra);
  scenic::Color color(bgra[2], bgra[1], bgra[0], bgra[3]);
  EXPECT_GT(histogram[color], 0u);
  histogram.erase(color);

  // This assert is written this way so that, when it fails, it prints out all
  // the unexpected colors
  EXPECT_EQ((std::map<scenic::Color, size_t>){}, histogram)
      << "Unexpected colors";
}

TEST_F(ScenicPixelTest, ViewCoordinates) {
  // Synchronously get display dimensions
  float display_width;
  float display_height;
  scenic_->GetDisplayInfo([this, &display_width, &display_height](
                              fuchsia::ui::gfx::DisplayInfo display_info) {
    display_width = static_cast<float>(display_info.width_in_px);
    display_height = static_cast<float>(display_info.height_in_px);
    QuitLoop();
  });
  RunLoop();

  scenic::CoordinateTestView view(CreatePresentationContext());
  RunUntilPresent(&view);

  fuchsia::ui::scenic::ScreenshotData screenshot = TakeScreenshot();
  std::vector<uint8_t> data;
  EXPECT_TRUE(fsl::VectorFromVmo(screenshot.data, &data))
      << "Failed to read screenshot";

  auto get_color_at_coordinates = [&display_width, &display_height, &data](
                                      float x, float y) -> scenic::Color {
    auto pixels = reinterpret_cast<scenic::Color*>(data.data());
    uint32_t index_x = x * display_width;
    uint32_t index_y = y * display_height;
    uint32_t index = index_y * display_width + index_x;
    return pixels[index];
  };

  EXPECT_EQ(scenic::Color({0, 0, 0, 255}),
            get_color_at_coordinates(.25f, .25f));
  EXPECT_EQ(scenic::Color({0, 0, 255, 255}),
            get_color_at_coordinates(.25f, .75f));
  EXPECT_EQ(scenic::Color({255, 0, 0, 255}),
            get_color_at_coordinates(.75f, .25f));
  EXPECT_EQ(scenic::Color({255, 0, 255, 255}),
            get_color_at_coordinates(.75f, .75f));
  EXPECT_EQ(scenic::Color({0, 255, 0, 255}),
            get_color_at_coordinates(.5f, .5f));
}

// Draws and tests the following coordinate test pattern without views:
// ___________________________________
// |                |                |
// |     BLACK      |        RED     |
// |           _____|_____           |
// |___________|  GREEN  |___________|
// |           |_________|           |
// |                |                |
// |      BLUE      |     MAGENTA    |
// |________________|________________|
//
TEST_F(ScenicPixelTest, GlobalCoordinates) {
  // Synchronously get display dimensions
  float display_width;
  float display_height;
  scenic_->GetDisplayInfo([this, &display_width, &display_height](
                              fuchsia::ui::gfx::DisplayInfo display_info) {
    display_width = static_cast<float>(display_info.width_in_px);
    display_height = static_cast<float>(display_info.height_in_px);
    QuitLoop();
  });
  RunLoop();

  // Initialize session
  auto unique_session = std::make_unique<scenic::Session>(scenic_.get());
  auto session = unique_session.get();
  session->set_error_handler([this](zx_status_t status) {
    FXL_LOG(ERROR) << "Session terminated.";
    QuitLoop();
  });

  scenic::DisplayCompositor compositor(session);
  scenic::LayerStack layer_stack(session);
  scenic::Layer layer(session);
  scenic::Renderer renderer(session);
  scenic::Scene scene(session);
  scenic::Camera camera(scene);

  float eye_position[3] = {display_width / 2.f, display_height / 2.f, -1001};
  float look_at[3] = {display_width / 2.f, display_height / 2.f, 1};
  float up[3] = {0, -1, 0};
  camera.SetTransform(eye_position, look_at, up);

  compositor.SetLayerStack(layer_stack);
  layer_stack.AddLayer(layer);
  layer.SetSize(display_width, display_height);
  layer.SetRenderer(renderer);
  renderer.SetCamera(camera.id());

  // Set up lights.
  scenic::AmbientLight ambient_light(session);
  scene.AddLight(ambient_light);
  ambient_light.SetColor(1.f, 1.f, 1.f);

  // Create an EntityNode to serve as the scene root.
  scenic::EntityNode root_node(session);
  scene.AddChild(root_node.id());

  static const float pane_width = display_width / 2;
  static const float pane_height = display_height / 2;

  for (uint32_t i = 0; i < 2; i++) {
    for (uint32_t j = 0; j < 2; j++) {
      scenic::Rectangle pane_shape(session, pane_width, pane_height);
      scenic::Material pane_material(session);
      pane_material.SetColor(i * 255.f, 0, j * 255.f, 255);

      scenic::ShapeNode pane_node(session);
      pane_node.SetShape(pane_shape);
      pane_node.SetMaterial(pane_material);
      pane_node.SetTranslation((i + 0.5) * pane_width, (j + 0.5) * pane_height,
                               -20);
      root_node.AddChild(pane_node);
    }
  }

  scenic::Rectangle pane_shape(session, display_width / 4, display_height / 4);
  scenic::Material pane_material(session);
  pane_material.SetColor(0, 255, 0, 255);

  scenic::ShapeNode pane_node(session);
  pane_node.SetShape(pane_shape);
  pane_node.SetMaterial(pane_material);
  pane_node.SetTranslation(0.5 * display_width, 0.5 * display_height, -40);
  root_node.AddChild(pane_node);

  // Actual tests. Test the same scene with an orthographic and perspective
  // camera.
  std::string camera_type[2] = {"orthographic", "perspective"};
  float fov[2] = {0, 2 * atan((display_height / 2.f) / abs(eye_position[2]))};

  for (int i = 0; i < 2; i++) {
    FXL_LOG(INFO) << "Testing " << camera_type[i] << " camera";
    camera.SetProjection(fov[i]);

    session->Present(
        0, [this](fuchsia::images::PresentationInfo info) { QuitLoop(); });
    RunLoop();

    fuchsia::ui::scenic::ScreenshotData screenshot = TakeScreenshot();
    std::vector<uint8_t> data;
    EXPECT_TRUE(fsl::VectorFromVmo(screenshot.data, &data))
        << "Failed to read screenshot";

    auto get_color_at_coordinates = [&display_width, &display_height, &data](
                                        float x, float y) -> scenic::Color {
      auto pixels = reinterpret_cast<scenic::Color*>(data.data());
      uint32_t index_x = x * display_width;
      uint32_t index_y = y * display_height;
      uint32_t index = index_y * display_width + index_x;
      return pixels[index];
    };

    EXPECT_EQ(scenic::Color({0, 0, 0, 255}),
              get_color_at_coordinates(.25f, .25f));
    EXPECT_EQ(scenic::Color({0, 0, 255, 255}),
              get_color_at_coordinates(.25f, .75f));
    EXPECT_EQ(scenic::Color({255, 0, 0, 255}),
              get_color_at_coordinates(.75f, .25f));
    EXPECT_EQ(scenic::Color({255, 0, 255, 255}),
              get_color_at_coordinates(.75f, .75f));
    EXPECT_EQ(scenic::Color({0, 255, 0, 255}),
              get_color_at_coordinates(.5f, .5f));
  }
}

// Draws a white rectangle on a black background rendered with a stereo
// camera, which produces an image something like this:
// _____________________________________
// |                                   |
// |   ___________       ___________   |
// |   |         |       |         |   |
// |   |         |       |         |   |
// |   |  WHITE  | BLACK |  WHITE  |   |
// |   |         |       |         |   |
// |   |_________|       |_________|   |
// |                                   |
// |___________________________________|
//

TEST_F(ScenicPixelTest, StereoCamera) {
  // Synchronously get display dimensions
  float display_width;
  float display_height;
  scenic_->GetDisplayInfo([this, &display_width, &display_height](
                              fuchsia::ui::gfx::DisplayInfo display_info) {
    display_width = static_cast<float>(display_info.width_in_px);
    display_height = static_cast<float>(display_info.height_in_px);
    QuitLoop();
  });
  RunLoop();

  static const float viewport_width = display_width / 2;
  static const float viewport_height = display_height;

  // Initialize session
  auto unique_session = std::make_unique<scenic::Session>(scenic_.get());
  auto session = unique_session.get();
  session->set_error_handler([this](zx_status_t status) {
    FXL_LOG(ERROR) << "Session terminated.";
    QuitLoop();
  });

  scenic::DisplayCompositor compositor(session);
  scenic::LayerStack layer_stack(session);
  scenic::Layer layer(session);
  scenic::Renderer renderer(session);
  scenic::Scene scene(session);
  scenic::StereoCamera camera(scene);

  float camera_offset = 1001;
  float eye_position[3] = {display_width / 2.f, display_height / 2.f,
                           -camera_offset};
  float look_at[3] = {display_width / 2.f, display_height / 2.f, 1};
  float up[3] = {0, -1, 0};
  camera.SetTransform(eye_position, look_at, up);

  float fovy = 2 * atan((display_height / 2.f) / abs(eye_position[2]));
  glm::mat4 projection = glm::perspective(
      fovy, viewport_width / viewport_height, 0.1f, camera_offset);
  projection = glm::scale(projection, glm::vec3(1.f, -1.f, 1.f));

  camera.SetStereoProjection(glm::value_ptr(projection),
                             glm::value_ptr(projection));

  compositor.SetLayerStack(layer_stack);
  layer_stack.AddLayer(layer);
  layer.SetSize(display_width, display_height);
  layer.SetRenderer(renderer);
  renderer.SetCamera(camera.id());

  // Set up lights.
  scenic::AmbientLight ambient_light(session);
  scene.AddLight(ambient_light);
  ambient_light.SetColor(1.f, 1.f, 1.f);

  // Create an EntityNode to serve as the scene root.
  scenic::EntityNode root_node(session);
  scene.AddChild(root_node.id());

  static const float pane_width = viewport_width / 2;
  static const float pane_height = viewport_height / 2;

  glm::vec3 translation(display_width * 0.5, display_height * 0.5, -10);

  scenic::Rectangle pane_shape(session, pane_width, pane_height);

  scenic::Material pane_material(session);
  pane_material.SetColor(255, 255, 255, 255);

  scenic::ShapeNode pane_shape_node(session);
  pane_shape_node.SetShape(pane_shape);
  pane_shape_node.SetMaterial(pane_material);
  pane_shape_node.SetTranslation(translation.x, translation.y, translation.z);
  root_node.AddChild(pane_shape_node);

  session->Present(
      0, [this](fuchsia::images::PresentationInfo info) { QuitLoop(); });
  RunLoop();

  fuchsia::ui::scenic::ScreenshotData screenshot = TakeScreenshot();
  std::vector<uint8_t> data;
  EXPECT_TRUE(fsl::VectorFromVmo(screenshot.data, &data))
      << "Failed to read screenshot";

  auto get_color_at_coordinates = [&display_width, &display_height, &data](
                                      float x, float y) -> scenic::Color {
    auto pixels = reinterpret_cast<scenic::Color*>(data.data());
    uint32_t index_x = x * display_width;
    uint32_t index_y = y * display_height;
    uint32_t index = index_y * display_width + index_x;
    return pixels[index];
  };

  // Color array to index 0=BLACK 1=WHITE
  scenic::Color colors[2] = {scenic::Color({0, 0, 0, 0}),
                             scenic::Color({255, 255, 255, 255})};

  // Expected results by index into colors array. Column major.
  // Note how this is a transposed, low-res version of the scene being drawn.
  // clang-format off
  int expected[8][4] = {{0, 0, 0, 0},
                        {0, 1, 1, 0},
                        {0, 1, 1, 0},
                        {0, 0, 0, 0},
                        {0, 0, 0, 0},
                        {0, 1, 1, 0},
                        {0, 1, 1, 0},
                        {0, 0, 0, 0}};
  // clang-format on

  // Test 8 columns of 4 samples each
  int num_x_samples = 8;
  int num_y_samples = 4;
  float x_step = 1.f / num_x_samples;
  float y_step = 1.f / num_y_samples;
  // i maps to x, j maps to y
  for (int i = 0; i < num_x_samples; i++) {
    for (int j = 0; j < num_y_samples; j++) {
      float x = x_step / 2 + i * x_step;
      float y = y_step / 2 + j * y_step;
      EXPECT_EQ(colors[expected[i][j]], get_color_at_coordinates(x, y))
          << "i = " << i << ", j = " << j << ", Sample Location: {" << x << ", "
          << y << "}";
    }
  }
}

// At a high level this test puts a camera inside a cube where each face is a
// different color, then uses a pose buffer to point the camera at different
// faces, using the colors to verify the pose buffer is working as expected.

VK_TEST_F(ScenicPixelTest, PoseBuffer) {
  // Synchronously get display dimensions
  float display_width;
  float display_height;
  scenic_->GetDisplayInfo([this, &display_width, &display_height](
                              fuchsia::ui::gfx::DisplayInfo display_info) {
    display_width = static_cast<float>(display_info.width_in_px);
    display_height = static_cast<float>(display_info.height_in_px);
    QuitLoop();
  });
  RunLoop();

  // Initialize session
  auto unique_session = std::make_unique<scenic::Session>(scenic_.get());
  auto session = unique_session.get();
  session->set_error_handler([this](zx_status_t status) {
    FXL_LOG(ERROR) << "Session terminated.";
    QuitLoop();
  });

  scenic::DisplayCompositor compositor(session);
  scenic::LayerStack layer_stack(session);
  scenic::Layer layer(session);
  scenic::Renderer renderer(session);
  scenic::Scene scene(session);
  scenic::StereoCamera camera(scene);

  static const float viewport_width = display_width / 2;
  static const float viewport_height = display_height;
  static const float camera_offset = 500;
  // View matrix matches vulkan clip space +Y down, looking in direction of +Z
  static const glm::vec3 eye(display_width / 2.f, display_height / 2.f,
                             -camera_offset);
  static const glm::vec3 look_at(eye + glm::vec3(0, 0, 1));
  static const glm::vec3 up(0, -1, 0);

  camera.SetTransform(glm::value_ptr(eye), glm::value_ptr(look_at),
                      glm::value_ptr(up));

  glm::mat4 projection =
      glm::perspective(glm::radians(120.f), viewport_width / viewport_height,
                       0.1f, camera_offset);
  // projection = glm::scale(projection, glm::vec3(1.f, -1.f, 1.f));

  glm::mat4 clip(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
                 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 1.0f);
  projection = clip * projection;

  glm::mat4 view = glm::lookAt(eye, look_at, up);

  camera.SetStereoProjection(glm::value_ptr(projection),
                             glm::value_ptr(projection));

  compositor.SetLayerStack(layer_stack);
  layer_stack.AddLayer(layer);
  layer.SetSize(display_width, display_height);
  layer.SetRenderer(renderer);
  renderer.SetCamera(camera.id());

  // Set up lights.
  scenic::AmbientLight ambient_light(session);
  scene.AddLight(ambient_light);
  ambient_light.SetColor(1.f, 1.f, 1.f);

  // Create an EntityNode to serve as the scene root.
  scenic::EntityNode root_node(session);
  scene.AddChild(root_node.id());

  // Configure PoseBuffer

  const size_t kVmoSize = PAGE_SIZE;
  zx_status_t status;

  auto vulkan_queues =
      scenic_impl::gfx::test::VkSessionTest::CreateVulkanDeviceQueues();
  auto device = vulkan_queues->vk_device();
  auto physical_device = vulkan_queues->vk_physical_device();

  // TODO(SCN-1369): Scenic may use a different set of bits when creating a
  // buffer, resulting in a memory pool mismatch.
  const vk::BufferUsageFlags kUsageFlags =
      vk::BufferUsageFlagBits::eTransferSrc |
      vk::BufferUsageFlagBits::eTransferDst |
      vk::BufferUsageFlagBits::eStorageTexelBuffer |
      vk::BufferUsageFlagBits::eStorageBuffer |
      vk::BufferUsageFlagBits::eIndexBuffer |
      vk::BufferUsageFlagBits::eVertexBuffer;

  auto memory_requirements =
      scenic_impl::gfx::test::VkSessionTest::GetBufferRequirements(
          device, kVmoSize, kUsageFlags);
  auto memory = scenic_impl::gfx::test::VkSessionTest::AllocateExportableMemory(
      device, physical_device, memory_requirements,
      vk::MemoryPropertyFlagBits::eDeviceLocal |
          vk::MemoryPropertyFlagBits::eHostVisible);

  // If we can't make memory that is both host-visible and device-local, we
  // can't run this test.
  if (!memory) {
    FXL_LOG(INFO)
        << "Could not find UMA compatible memory pool, aborting test.";
    return;
  }

  zx::vmo pose_buffer_vmo =
      scenic_impl::gfx::test::VkSessionTest::ExportMemoryAsVmo(
          device, vulkan_queues->dispatch_loader(), memory);

  zx::vmo remote_vmo;
  status = pose_buffer_vmo.duplicate(ZX_RIGHT_SAME_RIGHTS, &remote_vmo);
  FXL_DCHECK(status == ZX_OK);

  zx_time_t base_time = zx::clock::get_monotonic().get();
  // Normally the time interval is the period of time between each entry in the
  // pose buffer. In this example we only use one entry so the time interval is
  // pretty meaningless. Set to 1 for simplicity (see ARGO-21).
  zx_time_t time_interval = 1;
  uint32_t num_entries = 1;

  scenic::Memory mem(session, std::move(remote_vmo), kVmoSize,
                     fuchsia::images::MemoryType::VK_DEVICE_MEMORY);
  scenic::Buffer pose_buffer(mem, 0, kVmoSize);

  camera.SetPoseBuffer(pose_buffer, num_entries, base_time, time_interval);

  // Setup Scene.

  float pane_width = camera_offset / 2.f;
  scenic::Rectangle pane_shape(session, pane_width, pane_width);

  static const int num_panes = 6;

  scenic::Color colors[num_panes] = {
      scenic::Color({255, 0, 0, 255}),    // RED
      scenic::Color({0, 255, 255, 255}),  // CYAN
      scenic::Color({0, 255, 0, 255}),    // GREEN
      scenic::Color({255, 0, 255, 255}),  // MAGENTA
      scenic::Color({0, 0, 255, 255}),    // BLUE
      scenic::Color({255, 255, 0, 255}),  // YELLOW
  };

  static const float pane_offset = pane_width / 2;

  glm::vec3 translations[num_panes] = {
      eye + glm::vec3(0, 0, pane_offset),   // In front of camera.
      eye + glm::vec3(0, 0, -pane_offset),  // Behind camera.
      eye + glm::vec3(-pane_offset, 0, 0),  // Left of Camera
      eye + glm::vec3(pane_offset, 0, 0),   // Right of camera
      eye + glm::vec3(0, -pane_offset, 0),  // Above Camera
      eye + glm::vec3(0, pane_offset, 0),   // Below Camera
  };

  static const float pi = glm::pi<float>();
  glm::quat orientations[num_panes] = {
      glm::quat(),  // identity quaternion
      glm::angleAxis(pi, glm::vec3(1, 0, 0)),
      glm::angleAxis(-pi / 2, glm::vec3(0, 1, 0)),
      glm::angleAxis(pi / 2, glm::vec3(0, 1, 0)),
      glm::angleAxis(pi / 2, glm::vec3(1, 0, 0)),
      glm::angleAxis(-pi / 2, glm::vec3(1, 0, 0)),
  };

  for (int i = 0; i < num_panes; i++) {
    scenic::Color color = colors[i];
    glm::vec3 translation = translations[i];
    glm::quat orientation = orientations[i];

    FXL_LOG(ERROR) << "translation: " << glm::to_string(translation);
    FXL_LOG(ERROR) << "orientation: " << glm::to_string(orientation);

    scenic::Material pane_material(session);
    pane_material.SetColor(color.r, color.g, color.b, color.a);
    scenic::ShapeNode pane_shape_node(session);
    pane_shape_node.SetShape(pane_shape);
    pane_shape_node.SetMaterial(pane_material);
    pane_shape_node.SetTranslation(translation.x, translation.y, translation.z);
    pane_shape_node.SetRotation(orientation.x, orientation.y, orientation.z,
                                orientation.w);
    root_node.AddChild(pane_shape_node);
  }

  static const int num_quaternions = 8;

  glm::quat quaternions[num_quaternions] = {
      glm::quat(),                                 // dead ahead
      glm::angleAxis(pi, glm::vec3(0, 0, 1)),      // dead ahead but upside down
      glm::angleAxis(pi, glm::vec3(1, 0, 0)),      // behind around X
      glm::angleAxis(pi, glm::vec3(0, 1, 0)),      // behind around Y
      glm::angleAxis(pi / 2, glm::vec3(0, 1, 0)),  // left
      glm::angleAxis(-pi / 2, glm::vec3(0, 1, 0)),  // right
      glm::angleAxis(pi / 2, glm::vec3(1, 0, 0)),   // up
      glm::angleAxis(-pi / 2, glm::vec3(1, 0, 0)),  // down
  };

  int expected_color_index[num_quaternions] = {0, 0, 1, 1, 2, 3, 4, 5};

  for (int i = 0; i < num_quaternions; i++) {
    // Put pose into pose buffer.
    // Only testing orientation so position is always the origin.
    // Quaternion describes head orientation, so invert it to get a transform
    // that takes you into head space.
    escher::hmd::Pose pose(glm::inverse(quaternions[i]), glm::vec3(0, 0, 0));

    // Use vmo::write here for test simplicity. In a real case the vmo should be
    // mapped into a vmar so we dont need a syscall per write
    zx_status_t status =
        pose_buffer_vmo.write(&pose, 0, sizeof(escher::hmd::Pose));
    FXL_DCHECK(status == ZX_OK);

    session->Present(
        0, [this](fuchsia::images::PresentationInfo info) { QuitLoop(); });
    RunLoop();

    fuchsia::ui::scenic::ScreenshotData screenshot = TakeScreenshot();
    std::vector<uint8_t> data;
    EXPECT_TRUE(fsl::VectorFromVmo(screenshot.data, &data))
        << "Failed to read screenshot";

    auto get_color_at_coordinates = [&display_width, &display_height, &data](
                                        float x, float y) -> scenic::Color {
      auto pixels = reinterpret_cast<scenic::Color*>(data.data());
      uint32_t index_x = x * display_width;
      uint32_t index_y = y * display_height;
      uint32_t index = index_y * display_width + index_x;
      return pixels[index];
    };

    EXPECT_EQ(colors[expected_color_index[i]],
              get_color_at_coordinates(0.25, 0.5))
        << "i = " << i;
  }
  device.freeMemory(memory);
}

TEST_F(ScenicPixelTest, Opacity) {
  constexpr int kNumTests = 3;

  // We use the same background/foreground color for each test iteration, but
  // vary the opacity.  When the opacity is 0% we expect the pure background
  // color, and when it is 100% we expect the pure foreground color.  When
  // opacity is 50% we expect a blend of the two.
  float opacities[kNumTests] = {0.f, 0.5f, 1.f};
  scenic::Color expected_colors[kNumTests] = {{0xff, 0x00, 0xf0, 0xff},
                                              {0x80, 0x80, 0x80, 0xff},
                                              {0x00, 0xff, 0x0f, 0xff}};

  for (int i = 0; i < kNumTests; ++i) {
    scenic::OpacityView view(CreatePresentationContext());

    view.set_background_color(0xff, 0x00, 0xf0);
    view.set_foreground_color(0x00, 0xff, 0x0f);
    view.set_foreground_opacity(opacities[i]);

    RunUntilPresent(&view);
    fuchsia::ui::scenic::ScreenshotData screenshot = TakeScreenshot();

    EXPECT_GT(screenshot.info.width, 0u);
    EXPECT_GT(screenshot.info.height, 0u);

    // We could assert on each pixel individually, but a histogram might give us
    // a more meaningful failure.
    std::map<scenic::Color, size_t> histogram = scenic::Histogram(screenshot);

    EXPECT_GT(histogram[expected_colors[i]], 0u);
    histogram.erase(expected_colors[i]);
    EXPECT_EQ((std::map<scenic::Color, size_t>){}, histogram)
        << "Unexpected colors";
  }
}

// TODO(SCN-1375): Blocked against hardware inability
// to provide accurate screenshots from the physical
// display. Our "TakeScreenshot()" method only grabs
// pixel data from Escher before it gets sent off to
// the display controller and thus cannot accurately
// capture color conversion information.
VK_TEST_F(ScenicPixelTest, DISABLED_Compositor) {
  // Synchronously get display dimensions.
  float display_width;
  float display_height;
  scenic_->GetDisplayInfo([this, &display_width, &display_height](
                              fuchsia::ui::gfx::DisplayInfo display_info) {
    display_width = static_cast<float>(display_info.width_in_px);
    display_height = static_cast<float>(display_info.height_in_px);
    QuitLoop();
  });
  RunLoop();

  // Initialize session.
  auto unique_session = std::make_unique<scenic::Session>(scenic_.get());
  auto session = unique_session.get();
  session->set_error_handler([this](zx_status_t status) {
    FXL_LOG(ERROR) << "Session terminated.";
    QuitLoop();
  });

  // Initialize components.
  scenic::DisplayCompositor compositor(session);
  scenic::LayerStack layer_stack(session);
  scenic::Layer layer(session);
  scenic::Renderer renderer(session);
  scenic::Scene scene(session);
  scenic::Camera camera(scene);

  // Color correction data
  std::array<float, 3> preoffsets = {0, 0, 0};
  std::array<float, 9> matrix = {.288299,  0.052709,  -0.257912,
                                 0.711701, 0.947291,  0.257912,
                                 0.000000, -0.000000, 1.000000};
  std::array<float, 3> postoffsets = {0, 0, 0};

  glm::mat4 glm_matrix(.288299, 0.052709, -0.257912, 0.00000, 0.711701,
                       0.947291, 0.257912, 0.00000, 0.000000, -0.000000,
                       1.000000, 0.00000, 0.000000, 0.000000, 0.00000, 1.00000);

  // Position camera at the center of the display, looking down
  float eye_position[3] = {display_width / 2.f, display_height / 2.f, -1001};
  float look_at[3] = {display_width / 2.f, display_height / 2.f, 1};
  float up[3] = {0, -1, 0};
  camera.SetTransform(eye_position, look_at, up);
  camera.SetProjection(0);

  // Setup.
  compositor.SetLayerStack(layer_stack);
  layer_stack.AddLayer(layer);
  layer.SetSize(display_width, display_height);
  layer.SetRenderer(renderer);
  renderer.SetCamera(camera.id());

  // Set up lights.
  scenic::AmbientLight ambient_light(session);
  scene.AddLight(ambient_light);
  ambient_light.SetColor(1.f, 1.f, 1.f);

  // Create an EntityNode to serve as the scene root.
  scenic::EntityNode root_node(session);
  scene.AddChild(root_node.id());

  static const float pane_width = display_width / 5;
  static const float pane_height = display_height;

  float colors[15] = {1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0};

  for (uint32_t i = 0; i < 5; i++) {
    scenic::Rectangle pane_shape(session, pane_width, pane_height);
    scenic::Material pane_material(session);
    pane_material.SetColor(255 * colors[3 * i], 255 * colors[3 * i + 1],
                           255 * colors[3 * i + 2], 255);

    scenic::ShapeNode pane_node(session);
    pane_node.SetShape(pane_shape);
    pane_node.SetMaterial(pane_material);
    pane_node.SetTranslation((i + 0.5) * pane_width, 0.5 * pane_height, -20);
    root_node.AddChild(pane_node);
  }

  // Display uncorrected version first.
  session->Present(
      0, [this](fuchsia::images::PresentationInfo info) { QuitLoop(); });
  RunLoop();

  // Take screenshot.
  fuchsia::ui::scenic::ScreenshotData prev_screenshot = TakeScreenshot();
  std::vector<uint8_t> prev_data;
  EXPECT_TRUE(fsl::VectorFromVmo(prev_screenshot.data, &prev_data))
      << "Failed to read screenshot";

  // Apply color correction.
  compositor.SetColorConversion(preoffsets, matrix, postoffsets);

  // Display color corrected version.
  session->Present(
      1000000, [this](fuchsia::images::PresentationInfo info) { QuitLoop(); });
  RunLoop();

  // Take screenshot.
  fuchsia::ui::scenic::ScreenshotData post_screenshot = TakeScreenshot();
  std::vector<uint8_t> post_data;
  EXPECT_TRUE(fsl::VectorFromVmo(post_screenshot.data, &post_data))
      << "Failed to read screenshot";

  // Lambda function for getting pixel based on normalized coordintes.
  auto get_color = [&display_width, &display_height](
                       std::vector<uint8_t>& pixel_data, float x,
                       float y) -> scenic::Color {
    auto pixels = reinterpret_cast<scenic::Color*>(pixel_data.data());
    uint32_t index_x = x * display_width;
    uint32_t index_y = y * display_height;
    uint32_t index = index_y * display_width + index_x;
    return pixels[index];
  };

  for (uint32_t i = 0; i < 5; i++) {
    scenic::Color prev_color = get_color(prev_data, i * .2, 0.5);
    scenic::Color post_color = get_color(post_data, i * .2, 0.5);

    glm::vec4 vec =
        glm_matrix * glm::vec4(prev_color.r, prev_color.g, prev_color.b, 1);
    scenic::Color res(vec.x, vec.y, vec.z, vec.w);
    EXPECT_EQ(res, post_color);
  }
}

// This test sets up a scene, takes a screenshot, rotates display configuration
// by 90 degrees and takes a second screenshot, then makes sure that the pixels
// in both screenshots map onto each other how you would expect.
VK_TEST_F(ScenicPixelTest, RotationTest) {
  // Synchronously get display dimensions.
  float display_width;
  float display_height;
  scenic_->GetDisplayInfo([this, &display_width, &display_height](
                              fuchsia::ui::gfx::DisplayInfo display_info) {
    display_width = static_cast<float>(display_info.width_in_px);
    display_height = static_cast<float>(display_info.height_in_px);
    QuitLoop();
  });
  RunLoop();

  // Initialize session.
  auto unique_session = std::make_unique<scenic::Session>(scenic_.get());
  auto session = unique_session.get();
  session->set_error_handler([this](zx_status_t status) {
    FXL_LOG(ERROR) << "Session terminated.";
    QuitLoop();
  });

  // Initialize components.
  scenic::DisplayCompositor compositor(session);
  scenic::LayerStack layer_stack(session);
  scenic::Layer layer(session);
  scenic::Renderer renderer(session);
  scenic::Scene scene(session);
  scenic::Camera camera(scene);

  // Position camera at the center of the display, looking down
  float eye_position[3] = {display_width / 2.f, display_height / 2.f, -1001};
  float look_at[3] = {display_width / 2.f, display_height / 2.f, 1};
  float up[3] = {0, -1, 0};
  camera.SetTransform(eye_position, look_at, up);
  camera.SetProjection(0);

  // Setup.
  compositor.SetLayerStack(layer_stack);
  layer_stack.AddLayer(layer);
  layer.SetSize(display_width, display_height);
  layer.SetRenderer(renderer);
  renderer.SetCamera(camera.id());

  // Set up lights.
  scenic::AmbientLight ambient_light(session);
  scene.AddLight(ambient_light);
  ambient_light.SetColor(1.f, 1.f, 1.f);

  // Create an EntityNode to serve as the scene root.
  scenic::EntityNode root_node(session);
  scene.AddChild(root_node.id());

  static const float pane_width = display_width / 5;
  static const float pane_height = display_height;

  // For this test, create 5 vertical bands. This is an array of
  // the rgb colors for each of the five bands that will be
  // created below.
  float colors[15] = {1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0};

  for (uint32_t i = 0; i < 5; i++) {
    scenic::Rectangle pane_shape(session, pane_width, pane_height);
    scenic::Material pane_material(session);
    pane_material.SetColor(255 * colors[3 * i], 255 * colors[3 * i + 1],
                           255 * colors[3 * i + 2], 255);

    scenic::ShapeNode pane_node(session);
    pane_node.SetShape(pane_shape);
    pane_node.SetMaterial(pane_material);
    pane_node.SetTranslation((i + 0.5) * pane_width, 0.5 * pane_height, -20);
    root_node.AddChild(pane_node);
  }

  // Display unrotated version first.
  session->Present(
      0, [this](fuchsia::images::PresentationInfo info) { QuitLoop(); });
  RunLoop();

  // Take screenshot.
  fuchsia::ui::scenic::ScreenshotData prev_screenshot = TakeScreenshot();
  std::vector<uint8_t> prev_data;
  uint32_t prev_width = prev_screenshot.info.width;
  uint32_t prev_height = prev_screenshot.info.height;
  EXPECT_TRUE(fsl::VectorFromVmo(prev_screenshot.data, &prev_data))
      << "Failed to read screenshot";

  // Rotate 90 degrees
  compositor.SetLayoutRotation(90);

  // Display rotated version.
  session->Present(
      1000000, [this](fuchsia::images::PresentationInfo info) { QuitLoop(); });
  RunLoop();

  // Take screenshot.
  fuchsia::ui::scenic::ScreenshotData post_screenshot = TakeScreenshot();
  std::vector<uint8_t> post_data;
  uint32_t post_width = post_screenshot.info.width;
  uint32_t post_height = post_screenshot.info.height;
  EXPECT_TRUE(fsl::VectorFromVmo(post_screenshot.data, &post_data))
      << "Failed to read screenshot";

  // The pre and post width and height should be the reverse of eachother.
  EXPECT_TRUE(prev_width == post_height);
  EXPECT_TRUE(prev_height == post_width);

  // Lambda function for getting pixel values from the pre-rotated screenshot.
  auto get_prev_color = [&prev_width, &prev_data](float x,
                                                  float y) -> scenic::Color {
    auto pixels = reinterpret_cast<scenic::Color*>(prev_data.data());
    uint32_t index = y * prev_width + x;
    return pixels[index];
  };

  // Lambda function for getting pixel values from the post-rotated screenshot.
  auto get_post_color = [&post_width, &post_data](float x,
                                                  float y) -> scenic::Color {
    auto pixels = reinterpret_cast<scenic::Color*>(post_data.data());
    uint32_t index = y * post_width + x;
    return pixels[index];
  };

  // All of the colors should be transposed.
  for (uint32_t x = 0; x < prev_width; x++) {
    for (uint32_t y = 0; y < prev_height; y++) {
      EXPECT_EQ(get_prev_color(x, y), get_post_color(y, x));
    }
  }
}

}  // namespace
