blob: 68ee186376d9f397df544624ee43821b41e2c355 [file] [log] [blame]
Hendrik Wagenaar302b74f2017-04-04 14:38:36 -07001#include <private/dvr/device_metrics.h>
2
3#include <cutils/properties.h>
4#include <private/dvr/head_mount_metrics.h>
5#include <private/dvr/identity_distortion.h>
Hendrik Wagenaar302b74f2017-04-04 14:38:36 -07006#include <private/dvr/polynomial_radial_distortion.h>
7#include <private/dvr/types.h>
8#include "include/private/dvr/display_metrics.h"
9
10namespace {
11
Hendrik Wagenaar302b74f2017-04-04 14:38:36 -070012static constexpr char kRPolynomial[] = "persist.dvr.r_poly";
13static constexpr char kGPolynomial[] = "persist.dvr.g_poly";
14static constexpr char kBPolynomial[] = "persist.dvr.b_poly";
15static constexpr char kLensDistance[] = "persist.dvr.lens_distance";
16static constexpr char kDisplayGap[] = "persist.dvr.display_gap";
17static constexpr char kVEyeToDisplay[] = "persist.dvr.v_eye_to_display";
18static constexpr char kFovIOBT[] = "persist.dvr.fov_iobt";
19static constexpr char kScreenSize[] = "persist.dvr.screen_size";
20
21bool StringToFloat(const char* str, float* result) {
22 char* endptr = nullptr;
23 *result = std::strtof(str, &endptr);
24 return !(str == endptr || !endptr);
25}
26
27std::vector<std::string> SplitString(const std::string& string_to_split,
28 char deliminator) {
29 std::vector<std::string> result;
30 std::string sub_string;
31 std::stringstream ss(string_to_split);
32 while (std::getline(ss, sub_string, deliminator))
33 result.push_back(sub_string);
34 return result;
35}
36
37std::vector<float> GetProperty(const char* name,
38 const std::vector<float>& default_values) {
39 char prop[PROPERTY_VALUE_MAX + 1] = {};
40 property_get(name, prop, "");
41 std::vector<std::string> values = SplitString(prop, ',');
42 std::vector<float> results;
43 for (const auto& value : values) {
44 float result = 0.0f;
45 if (StringToFloat(value.c_str(), &result)) {
46 results.push_back(static_cast<float>(result));
47 }
48 }
49 if (results.empty()) {
50 return default_values;
51 }
52 return results;
53}
54
55float GetProperty(const char* name, float default_value) {
56 char prop[PROPERTY_VALUE_MAX + 1] = {};
57 property_get(name, prop, "");
58 float result = 0.0f;
59 if (StringToFloat(prop, &result)) {
60 return static_cast<float>(result);
61 }
62 return default_value;
63}
64
65float GetInterLensDistance() { return GetProperty(kLensDistance, 0.064f); }
66
67float GetDisplayGap() { return GetProperty(kDisplayGap, 0.0f); }
68
Hendrik Wagenaarf8b1ef42017-04-18 15:12:30 -070069float GetTrayToLensDistance() { return 0.035f; }
70
71float GetVEyeToDisplay() { return GetProperty(kVEyeToDisplay, 0.042f); }
Hendrik Wagenaar302b74f2017-04-04 14:38:36 -070072
73android::dvr::vec2 GetDisplaySize() {
74 static const std::vector<float> default_size = {0.0742177f, 0.131943f};
75 std::vector<float> sizes = GetProperty(kScreenSize, default_size);
76 if (sizes.size() != 0)
77 sizes = default_size;
78 return android::dvr::vec2(sizes[0], sizes[1]);
79}
80
81std::vector<float> GetMaxFOVs() {
82 static const std::vector<float> defaults = {43.7f, 47.8f, 54.2f, 54.2f};
83 std::vector<float> fovs = GetProperty(kFovIOBT, defaults);
84 if (fovs.size() != 4)
85 fovs = defaults;
86 for (auto& value : fovs) {
87 value = value * M_PI / 180.0f;
88 }
89 return fovs;
90}
91
92static const android::dvr::HeadMountMetrics::VerticalAlignment
93 kDefaultVerticalAlignment = android::dvr::HeadMountMetrics::kCenter;
94
95// Default border size in meters.
96static const float kScreenBorderSize = 0.004f;
97
98// Refresh rate.
99static const float kScreenRefreshRate = 60.0f;
100
101// Default display orientation is portrait.
102static const android::dvr::DisplayOrientation kDisplayOrientation =
103 android::dvr::DisplayOrientation::kPortrait;
104
105} // anonymous namespace
106
107namespace android {
108namespace dvr {
109
110HeadMountMetrics CreateHeadMountMetrics(const FieldOfView& l_fov,
111 const FieldOfView& r_fov) {
112 static const std::vector<float> default_r = {
Hendrik Wagenaarf8b1ef42017-04-18 15:12:30 -0700113 0.00103f, 2.63917f, -7.14427f, 8.98036f, -4.10586f, 0.83705f, 0.00130f};
Hendrik Wagenaar302b74f2017-04-04 14:38:36 -0700114 static const std::vector<float> default_g = {
Hendrik Wagenaarf8b1ef42017-04-18 15:12:30 -0700115 0.08944f, 2.26005f, -6.30924f, 7.94561f, -3.22788f, 0.45577f, 0.07300f};
Hendrik Wagenaar302b74f2017-04-04 14:38:36 -0700116 static const std::vector<float> default_b = {
Hendrik Wagenaarf8b1ef42017-04-18 15:12:30 -0700117 0.16364f, 1.94083f, -5.55033f, 6.89578f, -2.19053f, -0.04050f, 0.17380f};
Hendrik Wagenaar302b74f2017-04-04 14:38:36 -0700118 std::vector<float> poly_r = GetProperty(kRPolynomial, default_r);
119 std::vector<float> poly_g = GetProperty(kGPolynomial, default_g);
120 std::vector<float> poly_b = GetProperty(kBPolynomial, default_b);
Hendrik Wagenaar302b74f2017-04-04 14:38:36 -0700121
122 std::shared_ptr<ColorChannelDistortion> distortion_r(
Hendrik Wagenaarf8b1ef42017-04-18 15:12:30 -0700123 new PolynomialRadialDistortion(poly_r));
Hendrik Wagenaar302b74f2017-04-04 14:38:36 -0700124 std::shared_ptr<ColorChannelDistortion> distortion_g(
Hendrik Wagenaarf8b1ef42017-04-18 15:12:30 -0700125 new PolynomialRadialDistortion(poly_g));
Hendrik Wagenaar302b74f2017-04-04 14:38:36 -0700126 std::shared_ptr<ColorChannelDistortion> distortion_b(
Hendrik Wagenaarf8b1ef42017-04-18 15:12:30 -0700127 new PolynomialRadialDistortion(poly_b));
Hendrik Wagenaar302b74f2017-04-04 14:38:36 -0700128
Hendrik Wagenaarf8b1ef42017-04-18 15:12:30 -0700129 return HeadMountMetrics(GetInterLensDistance(), GetTrayToLensDistance(),
Hendrik Wagenaar302b74f2017-04-04 14:38:36 -0700130 GetVEyeToDisplay(), kDefaultVerticalAlignment, l_fov,
131 r_fov, distortion_r, distortion_g, distortion_b,
132 HeadMountMetrics::EyeOrientation::kCCW0Degrees,
133 HeadMountMetrics::EyeOrientation::kCCW0Degrees,
134 (GetInterLensDistance() - GetDisplayGap()) / 2.0f);
135}
136
137HeadMountMetrics CreateHeadMountMetrics() {
138 std::vector<float> fovs = GetMaxFOVs();
139 FieldOfView l_fov(fovs[1], fovs[0], fovs[2], fovs[3]);
140 FieldOfView r_fov(fovs[0], fovs[1], fovs[2], fovs[3]);
141 return CreateHeadMountMetrics(l_fov, r_fov);
142}
143
144DisplayMetrics CreateDisplayMetrics(vec2i screen_size) {
145 android::dvr::vec2 size_in_meters = GetDisplaySize();
146 vec2 meters_per_pixel(size_in_meters[0] / static_cast<float>(screen_size[0]),
147 size_in_meters[1] / static_cast<float>(screen_size[1]));
148 return DisplayMetrics(screen_size, meters_per_pixel, kScreenBorderSize,
149 1000.0f / kScreenRefreshRate, kDisplayOrientation);
150}
151
152HeadMountMetrics CreateUndistortedHeadMountMetrics() {
153 std::vector<float> fovs = GetMaxFOVs();
154 FieldOfView l_fov(fovs[1], fovs[0], fovs[2], fovs[3]);
155 FieldOfView r_fov(fovs[0], fovs[1], fovs[2], fovs[3]);
156 return CreateUndistortedHeadMountMetrics(l_fov, r_fov);
157}
158
159HeadMountMetrics CreateUndistortedHeadMountMetrics(const FieldOfView& l_fov,
160 const FieldOfView& r_fov) {
161 auto distortion_all = std::make_shared<IdentityDistortion>();
162
163 return HeadMountMetrics(GetInterLensDistance(), GetVEyeToDisplay(),
164 GetVEyeToDisplay(), kDefaultVerticalAlignment, l_fov,
165 r_fov, distortion_all, distortion_all, distortion_all,
166 HeadMountMetrics::EyeOrientation::kCCW0Degrees,
167 HeadMountMetrics::EyeOrientation::kCCW0Degrees,
168 (GetInterLensDistance() - GetDisplayGap()) / 2.0f);
169}
170
171} // namespace dvr
172} // namespace android