// Copyright (c) 2017 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 "device/vr/openvr/openvr_render_loop.h"

#include "base/metrics/histogram_functions.h"
#include "device/vr/openvr/openvr_api_wrapper.h"
#include "device/vr/openvr/openvr_gamepad_helper.h"
#include "device/vr/openvr/openvr_type_converters.h"
#include "ui/gfx/geometry/angle_conversions.h"
#include "ui/gfx/transform.h"

#if defined(OS_WIN)
#include "device/vr/windows/d3d11_texture_helper.h"
#endif

namespace device {

namespace {

// OpenVR reports the controllers pose of the controller's tip, while WebXR
// needs to report the pose of the controller's grip (centered on the user's
// palm.) This experimentally determined value is how far back along the Z axis
// in meters OpenVR's pose needs to be translated to align with WebXR's
// coordinate system.
const float kGripOffsetZMeters = 0.08f;

// WebXR reports a pointer pose separate from the grip pose, which represents a
// pointer ray emerging from the tip of the controller. OpenVR does not report
// anything like that, and most pointers are assumed to come straight from the
// controller's tip. For consistency with other WebXR backends we'll synthesize
// a pointer ray that's angled down slightly from the controller's handle,
// defined by this angle. Experimentally determined, should roughly point in the
// same direction as a user's outstretched index finger while holding a
// controller.
const float kPointerErgoAngleDegrees = -40.0f;

gfx::Transform HmdMatrix34ToTransform(const vr::HmdMatrix34_t& mat) {
  return gfx::Transform(mat.m[0][0], mat.m[0][1], mat.m[0][2], mat.m[0][3],
                        mat.m[1][0], mat.m[1][1], mat.m[1][2], mat.m[1][3],
                        mat.m[2][0], mat.m[2][1], mat.m[2][2], mat.m[2][3], 0,
                        0, 0, 1);
}

}  // namespace

OpenVRRenderLoop::OpenVRRenderLoop() : XRCompositorCommon() {}

OpenVRRenderLoop::~OpenVRRenderLoop() {
  Stop();
}

bool OpenVRRenderLoop::PreComposite() {
  texture_helper_.AllocateBackBuffer();
  return true;
}

bool OpenVRRenderLoop::SubmitCompositedFrame() {
  DCHECK(openvr_);
  vr::IVRCompositor* vr_compositor = openvr_->GetCompositor();
  DCHECK(vr_compositor);
  if (!vr_compositor)
    return false;

  vr::Texture_t texture;
  texture.handle = texture_helper_.GetBackbuffer().Get();
  texture.eType = vr::TextureType_DirectX;
  texture.eColorSpace = vr::ColorSpace_Auto;

  gfx::RectF left_bounds = texture_helper_.BackBufferLeft();
  gfx::RectF right_bounds = texture_helper_.BackBufferRight();

  vr::VRTextureBounds_t bounds[2];
  bounds[0] = {left_bounds.x(), left_bounds.y(),
               left_bounds.width() + left_bounds.x(),
               left_bounds.height() + left_bounds.y()};
  bounds[1] = {right_bounds.x(), right_bounds.y(),
               right_bounds.width() + right_bounds.x(),
               right_bounds.height() + right_bounds.y()};

  vr::EVRCompositorError error =
      vr_compositor->Submit(vr::EVREye::Eye_Left, &texture, &bounds[0]);
  if (error != vr::VRCompositorError_None) {
    return false;
  }
  error = vr_compositor->Submit(vr::EVREye::Eye_Right, &texture, &bounds[1]);
  if (error != vr::VRCompositorError_None) {
    return false;
  }
  vr_compositor->PostPresentHandoff();
  return true;
}

bool OpenVRRenderLoop::StartRuntime() {
  if (!openvr_) {
    openvr_ = std::make_unique<OpenVRWrapper>(true);
    if (!openvr_->IsInitialized()) {
      openvr_ = nullptr;
      return false;
    }

    openvr_->GetCompositor()->SuspendRendering(true);
    openvr_->GetCompositor()->SetTrackingSpace(
        vr::ETrackingUniverseOrigin::TrackingUniverseSeated);
  }

#if defined(OS_WIN)
  int32_t adapter_index;
  openvr_->GetSystem()->GetDXGIOutputInfo(&adapter_index);
  if (!texture_helper_.SetAdapterIndex(adapter_index) ||
      !texture_helper_.EnsureInitialized()) {
    openvr_ = nullptr;
    return false;
  }
#endif

  uint32_t width, height;
  openvr_->GetSystem()->GetRecommendedRenderTargetSize(&width, &height);
  texture_helper_.SetDefaultSize(gfx::Size(width, height));

  return true;
}

void OpenVRRenderLoop::StopRuntime() {
  if (openvr_)
    openvr_->GetCompositor()->SuspendRendering(true);
  openvr_ = nullptr;
}

void OpenVRRenderLoop::OnSessionStart() {
  // Reset the active states for all the controllers.
  for (uint32_t i = 0; i < vr::k_unMaxTrackedDeviceCount; ++i) {
    InputActiveState& input_active_state = input_active_states_[i];
    input_active_state.active = false;
    input_active_state.primary_input_pressed = false;
    input_active_state.device_class = vr::TrackedDeviceClass_Invalid;
    input_active_state.controller_role = vr::TrackedControllerRole_Invalid;
  }

  openvr_->GetCompositor()->SuspendRendering(false);

  // Measure the VrViewerType we are presenting with.
  std::string model =
      GetOpenVRString(openvr_->GetSystem(), vr::Prop_ModelNumber_String);
  VrViewerType type = VrViewerType::OPENVR_UNKNOWN;
  if (model == "Oculus Rift CV1")
    type = VrViewerType::OPENVR_RIFT_CV1;
  else if (model == "Vive MV")
    type = VrViewerType::OPENVR_VIVE;

  base::UmaHistogramSparse("VRViewerType", static_cast<int>(type));
}

mojom::XRGamepadDataPtr OpenVRRenderLoop::GetNextGamepadData() {
  if (!openvr_) {
    return nullptr;
  }
  return OpenVRGamepadHelper::GetGamepadData(openvr_->GetSystem());
}

mojom::VRPosePtr OpenVRRenderLoop::GetPose() {
  vr::TrackedDevicePose_t rendering_poses[vr::k_unMaxTrackedDeviceCount];

  TRACE_EVENT0("gpu", "WaitGetPoses");
  openvr_->GetCompositor()->WaitGetPoses(
      rendering_poses, vr::k_unMaxTrackedDeviceCount, nullptr, 0);

  mojom::VRPosePtr pose = mojo::ConvertTo<mojom::VRPosePtr>(
      rendering_poses[vr::k_unTrackedDeviceIndex_Hmd]);

  // Update WebXR input sources.
  DCHECK(pose);
  pose->input_state =
      GetInputState(rendering_poses, vr::k_unMaxTrackedDeviceCount);

  return pose;
}

mojom::XRFrameDataPtr OpenVRRenderLoop::GetNextFrameData() {
  mojom::XRFrameDataPtr frame_data = mojom::XRFrameData::New();
  frame_data->frame_id = next_frame_id_;

  if (openvr_) {
    frame_data->pose = GetPose();
    vr::Compositor_FrameTiming timing;
    timing.m_nSize = sizeof(vr::Compositor_FrameTiming);
    bool valid_time = openvr_->GetCompositor()->GetFrameTiming(&timing);
    if (valid_time) {
      frame_data->time_delta =
          base::TimeDelta::FromSecondsD(timing.m_flSystemTimeInSeconds);
    }
  }

  return frame_data;
}

void OpenVRRenderLoop::GetEnvironmentIntegrationProvider(
    mojom::XREnvironmentIntegrationProviderAssociatedRequest
        environment_provider) {
  // Environment integration is not supported. This call should not
  // be made on this device.
  mojo::ReportBadMessage("Environment integration is not supported.");
  return;
}

std::vector<mojom::XRInputSourceStatePtr> OpenVRRenderLoop::GetInputState(
    vr::TrackedDevicePose_t* poses,
    uint32_t count) {
  std::vector<mojom::XRInputSourceStatePtr> input_states;

  if (!openvr_)
    return input_states;

  // Loop through every device pose and determine which are controllers
  for (uint32_t i = vr::k_unTrackedDeviceIndex_Hmd + 1; i < count; ++i) {
    const vr::TrackedDevicePose_t& pose = poses[i];
    InputActiveState& input_active_state = input_active_states_[i];

    if (!pose.bDeviceIsConnected) {
      // If this was an active controller on the last frame report it as
      // disconnected.
      if (input_active_state.active) {
        input_active_state.active = false;
        input_active_state.primary_input_pressed = false;
        input_active_state.device_class = vr::TrackedDeviceClass_Invalid;
        input_active_state.controller_role = vr::TrackedControllerRole_Invalid;
      }
      continue;
    }

    // Is this a newly connected controller?
    bool newly_active = false;
    if (!input_active_state.active) {
      input_active_state.active = true;
      input_active_state.device_class =
          openvr_->GetSystem()->GetTrackedDeviceClass(i);
      newly_active = true;
    }

    // Skip over any tracked devices that aren't controllers.
    if (input_active_state.device_class != vr::TrackedDeviceClass_Controller) {
      continue;
    }

    device::mojom::XRInputSourceStatePtr state =
        device::mojom::XRInputSourceState::New();

    vr::VRControllerState_t controller_state;
    openvr_->GetSystem()->GetControllerState(i, &controller_state,
                                             sizeof(vr::VRControllerState_t));
    bool pressed = controller_state.ulButtonPressed &
                   vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Trigger);

    state->source_id = i;
    state->primary_input_pressed = pressed;
    state->primary_input_clicked =
        (!pressed && input_active_state.primary_input_pressed);

    input_active_state.primary_input_pressed = pressed;

    if (pose.bPoseIsValid) {
      state->grip = HmdMatrix34ToTransform(pose.mDeviceToAbsoluteTracking);
      // Scoot the grip matrix back a bit so that it actually lines up with the
      // user's palm.
      state->grip->Translate3d(0, 0, kGripOffsetZMeters);
    }

    // Poll controller roll per-frame, since OpenVR controllers can swap hands.
    vr::ETrackedControllerRole controller_role =
        openvr_->GetSystem()->GetControllerRoleForTrackedDeviceIndex(i);

    // If this is a newly active controller or if the handedness has changed
    // since the last update, re-send the controller's description.
    if (newly_active || controller_role != input_active_state.controller_role) {
      device::mojom::XRInputSourceDescriptionPtr desc =
          device::mojom::XRInputSourceDescription::New();

      // It's a handheld pointing device.
      desc->target_ray_mode = device::mojom::XRTargetRayMode::POINTING;

      // Set handedness.
      switch (controller_role) {
        case vr::TrackedControllerRole_LeftHand:
          desc->handedness = device::mojom::XRHandedness::LEFT;
          break;
        case vr::TrackedControllerRole_RightHand:
          desc->handedness = device::mojom::XRHandedness::RIGHT;
          break;
        default:
          desc->handedness = device::mojom::XRHandedness::NONE;
          break;
      }
      input_active_state.controller_role = controller_role;

      // OpenVR controller are fully 6DoF.
      desc->emulated_position = false;

      // Tweak the pointer transform so that it's angled down from the
      // grip. This should be a bit more ergonomic.
      desc->pointer_offset = gfx::Transform();
      desc->pointer_offset->RotateAboutXAxis(kPointerErgoAngleDegrees);

      state->description = std::move(desc);
    }

    input_states.push_back(std::move(state));
  }

  return input_states;
}

}  // namespace device
