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