Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 302b74ff authored by Hendrik Wagenaar's avatar Hendrik Wagenaar
Browse files

Update optics

* Specify optics via system properties

Bug: 36039976
Test: Ran on device

Change-Id: I7a38e5a9eb3b8a861f1997d5011ec109f5e79cca
parent 4df42025
Loading
Loading
Loading
Loading
+1 −3
Original line number Original line Diff line number Diff line
@@ -16,11 +16,9 @@ sourceFiles = [
    "eds.cpp",
    "eds.cpp",
    "eds_mesh.cpp",
    "eds_mesh.cpp",
    "composite_hmd.cpp",
    "composite_hmd.cpp",
    "cpu_thread_pose_updater.cpp",
    "display_metrics.cpp",
    "display_metrics.cpp",
    "distortion_renderer.cpp",
    "distortion_renderer.cpp",
    "lucid_metrics.cpp",
    "device_metrics.cpp",
    "lucid_pose_tracker.cpp",
    "lookup_radial_distortion.cpp",
    "lookup_radial_distortion.cpp",
    "polynomial_radial_distortion.cpp",
    "polynomial_radial_distortion.cpp",
]
]
+0 −86
Original line number Original line Diff line number Diff line
#include "include/private/dvr/cpu_thread_pose_updater.h"

#include <sys/prctl.h>
#include <unistd.h>

#define ATRACE_TAG ATRACE_TAG_INPUT
#include <utils/Trace.h>

#include <private/dvr/clock_ns.h>
#include <private/dvr/debug.h>

namespace android {
namespace dvr {

CpuThreadPoseUpdater::CpuThreadPoseUpdater()
    : stop_request_(false), update_period_us_(0), count_(0) {}

CpuThreadPoseUpdater::~CpuThreadPoseUpdater() { StopAndJoin(); }

void CpuThreadPoseUpdater::Start(volatile RawPosePair* mapped_pose_buffer,
                                 int period_us) {
  mapped_pose_buffer_ = mapped_pose_buffer;
  update_period_us_ = period_us;
  stop_request_ = false;

  // First buffer is odd (starts at 1), second is even (starts at 2).
  count_ = 0;
  mapped_pose_buffer_->pose1.Reset(++count_);
  mapped_pose_buffer_->pose2.Reset(++count_);

  update_thread_ = std::thread(&CpuThreadPoseUpdater::UpdateThread, this);
}

void CpuThreadPoseUpdater::StopAndJoin() {
  stop_request_ = true;
  if (update_thread_.joinable()) {
    update_thread_.join();
  }
}

void CpuThreadPoseUpdater::UpdateThread() {
  prctl(PR_SET_NAME, reinterpret_cast<intptr_t>("CpuPoseUpdater"),
        0, 0, 0);

  ATRACE_NAME(__PRETTY_FUNCTION__);
  for (;;) {
    if (stop_request_) {
      break;
    }

    ++count_;

    // Choose the writable pose based on whether count is odd or even.
    volatile RawPose* out_pose = nullptr;
    if (count_ & 1) {
      out_pose = &mapped_pose_buffer_->pose1;
    } else {
      out_pose = &mapped_pose_buffer_->pose2;
    }

    {
      ATRACE_NAME("GetPose");
      Posef pose = pose_tracker_.GetPose(GetSystemClockNs());
      out_pose->qx = pose.GetRotation().x();
      out_pose->qy = pose.GetRotation().y();
      out_pose->qz = pose.GetRotation().z();
      out_pose->qw = pose.GetRotation().w();
      out_pose->px = pose.GetPosition()[0];
      out_pose->py = pose.GetPosition()[1];
      out_pose->pz = pose.GetPosition()[2];
      // Atomically store the count so that it hits memory last:
      out_pose->count.store(count_, std::memory_order_release);
    }

    // Sleep to simulate the IMU update process.
    usleep(update_period_us_);
    // TODO(jbates) sleep_for returns immediately, we need to fix our toolchain!
    // int64_t c1 = GetSystemClockNs();
    // std::this_thread::sleep_for(std::chrono::milliseconds(10));
    // int64_t c2 = GetSystemClockNs();
    // fprintf(stderr, "%lld us\n", (long long)(c2 - c1) / 1000);
  }
}

}  // namesapce dvr
}  // namesapce android
+182 −0
Original line number Original line Diff line number Diff line
#include <private/dvr/device_metrics.h>

#include <cutils/properties.h>
#include <private/dvr/head_mount_metrics.h>
#include <private/dvr/identity_distortion.h>
#include <private/dvr/lookup_radial_distortion.h>
#include <private/dvr/polynomial_radial_distortion.h>
#include <private/dvr/types.h>
#include "include/private/dvr/display_metrics.h"

namespace {

static constexpr char kRGBPolynomialOffset[] = "persist.dvr.rgb_poly_offset";
static constexpr char kRPolynomial[] = "persist.dvr.r_poly";
static constexpr char kGPolynomial[] = "persist.dvr.g_poly";
static constexpr char kBPolynomial[] = "persist.dvr.b_poly";
static constexpr char kLensDistance[] = "persist.dvr.lens_distance";
static constexpr char kDisplayGap[] = "persist.dvr.display_gap";
static constexpr char kVEyeToDisplay[] = "persist.dvr.v_eye_to_display";
static constexpr char kFovIOBT[] = "persist.dvr.fov_iobt";
static constexpr char kScreenSize[] = "persist.dvr.screen_size";

bool StringToFloat(const char* str, float* result) {
  char* endptr = nullptr;
  *result = std::strtof(str, &endptr);
  return !(str == endptr || !endptr);
}

std::vector<std::string> SplitString(const std::string& string_to_split,
                                     char deliminator) {
  std::vector<std::string> result;
  std::string sub_string;
  std::stringstream ss(string_to_split);
  while (std::getline(ss, sub_string, deliminator))
    result.push_back(sub_string);
  return result;
}

std::vector<float> GetProperty(const char* name,
                               const std::vector<float>& default_values) {
  char prop[PROPERTY_VALUE_MAX + 1] = {};
  property_get(name, prop, "");
  std::vector<std::string> values = SplitString(prop, ',');
  std::vector<float> results;
  for (const auto& value : values) {
    float result = 0.0f;
    if (StringToFloat(value.c_str(), &result)) {
      results.push_back(static_cast<float>(result));
    }
  }
  if (results.empty()) {
    return default_values;
  }
  return results;
}

float GetProperty(const char* name, float default_value) {
  char prop[PROPERTY_VALUE_MAX + 1] = {};
  property_get(name, prop, "");
  float result = 0.0f;
  if (StringToFloat(prop, &result)) {
    return static_cast<float>(result);
  }
  return default_value;
}

float GetInterLensDistance() { return GetProperty(kLensDistance, 0.064f); }

float GetDisplayGap() { return GetProperty(kDisplayGap, 0.0f); }

float GetVEyeToDisplay() { return GetProperty(kVEyeToDisplay, 0.035f); }

android::dvr::vec2 GetDisplaySize() {
  static const std::vector<float> default_size = {0.0742177f, 0.131943f};
  std::vector<float> sizes = GetProperty(kScreenSize, default_size);
  if (sizes.size() != 0)
    sizes = default_size;
  return android::dvr::vec2(sizes[0], sizes[1]);
}

std::vector<float> GetMaxFOVs() {
  static const std::vector<float> defaults = {43.7f, 47.8f, 54.2f, 54.2f};
  std::vector<float> fovs = GetProperty(kFovIOBT, defaults);
  if (fovs.size() != 4)
    fovs = defaults;
  for (auto& value : fovs) {
    value = value * M_PI / 180.0f;
  }
  return fovs;
}

static const android::dvr::HeadMountMetrics::VerticalAlignment
    kDefaultVerticalAlignment = android::dvr::HeadMountMetrics::kCenter;

// Default border size in meters.
static const float kScreenBorderSize = 0.004f;

// Refresh rate.
static const float kScreenRefreshRate = 60.0f;

// Default display orientation is portrait.
static const android::dvr::DisplayOrientation kDisplayOrientation =
    android::dvr::DisplayOrientation::kPortrait;

}  // anonymous namespace

namespace android {
namespace dvr {

HeadMountMetrics CreateHeadMountMetrics(const FieldOfView& l_fov,
                                        const FieldOfView& r_fov) {
  static const std::vector<float> default_r = {
      -4.08519004f,  34.70282075f, -67.37781249f, 56.97304235f,
      -23.35768685f, 4.7199597f,   0.63198082f};
  static const std::vector<float> default_g = {
      4.43078318f, 3.47806617f, -20.58017398f, 20.85880414f,
      -8.4046504f, 1.61284685f, 0.8881761f};
  static const std::vector<float> default_b = {
      12.04141265f, -21.98112491f, 14.06758389f, -3.15245629f,
      0.36549102f,  0.05252705f,   0.99844279f};
  static const std::vector<float> default_offsets = {
      0.20971645238f, 0.15189450000f, 1.00096958278f};

  std::vector<float> poly_offsets =
      GetProperty(kRGBPolynomialOffset, default_offsets);
  std::vector<float> poly_r = GetProperty(kRPolynomial, default_r);
  std::vector<float> poly_g = GetProperty(kGPolynomial, default_g);
  std::vector<float> poly_b = GetProperty(kBPolynomial, default_b);
  if (poly_offsets.size() != 3)
    poly_offsets = default_offsets;

  std::shared_ptr<ColorChannelDistortion> distortion_r(
      new PolynomialRadialDistortion(poly_offsets[0], poly_r));
  std::shared_ptr<ColorChannelDistortion> distortion_g(
      new PolynomialRadialDistortion(poly_offsets[1], poly_g));
  std::shared_ptr<ColorChannelDistortion> distortion_b(
      new PolynomialRadialDistortion(poly_offsets[2], poly_b));

  return HeadMountMetrics(GetInterLensDistance(), GetVEyeToDisplay(),
                          GetVEyeToDisplay(), kDefaultVerticalAlignment, l_fov,
                          r_fov, distortion_r, distortion_g, distortion_b,
                          HeadMountMetrics::EyeOrientation::kCCW0Degrees,
                          HeadMountMetrics::EyeOrientation::kCCW0Degrees,
                          (GetInterLensDistance() - GetDisplayGap()) / 2.0f);
}

HeadMountMetrics CreateHeadMountMetrics() {
  std::vector<float> fovs = GetMaxFOVs();
  FieldOfView l_fov(fovs[1], fovs[0], fovs[2], fovs[3]);
  FieldOfView r_fov(fovs[0], fovs[1], fovs[2], fovs[3]);
  return CreateHeadMountMetrics(l_fov, r_fov);
}

DisplayMetrics CreateDisplayMetrics(vec2i screen_size) {
  android::dvr::vec2 size_in_meters = GetDisplaySize();
  vec2 meters_per_pixel(size_in_meters[0] / static_cast<float>(screen_size[0]),
                        size_in_meters[1] / static_cast<float>(screen_size[1]));
  return DisplayMetrics(screen_size, meters_per_pixel, kScreenBorderSize,
                        1000.0f / kScreenRefreshRate, kDisplayOrientation);
}

HeadMountMetrics CreateUndistortedHeadMountMetrics() {
  std::vector<float> fovs = GetMaxFOVs();
  FieldOfView l_fov(fovs[1], fovs[0], fovs[2], fovs[3]);
  FieldOfView r_fov(fovs[0], fovs[1], fovs[2], fovs[3]);
  return CreateUndistortedHeadMountMetrics(l_fov, r_fov);
}

HeadMountMetrics CreateUndistortedHeadMountMetrics(const FieldOfView& l_fov,
                                                   const FieldOfView& r_fov) {
  auto distortion_all = std::make_shared<IdentityDistortion>();

  return HeadMountMetrics(GetInterLensDistance(), GetVEyeToDisplay(),
                          GetVEyeToDisplay(), kDefaultVerticalAlignment, l_fov,
                          r_fov, distortion_all, distortion_all, distortion_all,
                          HeadMountMetrics::EyeOrientation::kCCW0Degrees,
                          HeadMountMetrics::EyeOrientation::kCCW0Degrees,
                          (GetInterLensDistance() - GetDisplayGap()) / 2.0f);
}

}  // namespace dvr
}  // namespace android
+0 −48
Original line number Original line Diff line number Diff line
#ifndef ANDROID_DVR_CPU_THREAD_POSE_UPDATER_H_
#define ANDROID_DVR_CPU_THREAD_POSE_UPDATER_H_

#include <atomic>
#include <thread>

#include <private/dvr/lucid_pose_tracker.h>
#include <private/dvr/raw_pose.h>

namespace android {
namespace dvr {

// Temporary version of pose updater that uses a CPU thread to update
// the pose buffer. Note that this thread starts and runs indefinitely
class CpuThreadPoseUpdater {
 public:
  CpuThreadPoseUpdater();
  ~CpuThreadPoseUpdater();

  // Start the thread to update the given buffer with the given number of
  // microseconds between updates.
  void Start(volatile RawPosePair* mapped_pose_buffer, int period_us);

  void StopAndJoin();

 private:
  void UpdateThread();

  volatile RawPosePair* mapped_pose_buffer_;

  // Pose update thread.
  std::thread update_thread_;

  volatile bool stop_request_;

  // Update period in microseconds.
  int update_period_us_;

  // Current pose count, used to avoid writing to the same buffer that is being
  // read by the GPU.
  uint32_t count_;
  LucidPoseTracker pose_tracker_;
};

}  // namespace dvr
}  // namespace android

#endif  // ANDROID_DVR_CPU_THREAD_POSE_UPDATER_H_
+3 −3
Original line number Original line Diff line number Diff line
#ifndef ANDROID_DVR_LUCID_METRICS_H_
#ifndef ANDROID_DVR_DEVICE_METRICS_H_
#define ANDROID_DVR_LUCID_METRICS_H_
#define ANDROID_DVR_DEVICE_METRICS_H_


#include <private/dvr/display_metrics.h>
#include <private/dvr/display_metrics.h>
#include <private/dvr/head_mount_metrics.h>
#include <private/dvr/head_mount_metrics.h>
@@ -19,4 +19,4 @@ DisplayMetrics CreateDisplayMetrics(vec2i screen_size);
}  // namespace dvr
}  // namespace dvr
}  // namespace android
}  // namespace android


#endif  // ANDROID_DVR_LUCID_METRICS_H_
#endif  // ANDROID_DVR_DEVICE_METRICS_H_
Loading