blob: 50c3e54bacebd9efaa953cb7a5e049e5559b22da [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
13static constexpr char kRGBPolynomialOffset[] = "persist.dvr.rgb_poly_offset";
14static constexpr char kRPolynomial[] = "persist.dvr.r_poly";
15static constexpr char kGPolynomial[] = "persist.dvr.g_poly";
16static constexpr char kBPolynomial[] = "persist.dvr.b_poly";
17static constexpr char kLensDistance[] = "persist.dvr.lens_distance";
18static constexpr char kDisplayGap[] = "persist.dvr.display_gap";
19static constexpr char kVEyeToDisplay[] = "persist.dvr.v_eye_to_display";
20static constexpr char kFovIOBT[] = "persist.dvr.fov_iobt";
21static constexpr char kScreenSize[] = "persist.dvr.screen_size";
22
23bool StringToFloat(const char* str, float* result) {
24 char* endptr = nullptr;
25 *result = std::strtof(str, &endptr);
26 return !(str == endptr || !endptr);
27}
28
29std::vector<std::string> SplitString(const std::string& string_to_split,
30 char deliminator) {
31 std::vector<std::string> result;
32 std::string sub_string;
33 std::stringstream ss(string_to_split);
34 while (std::getline(ss, sub_string, deliminator))
35 result.push_back(sub_string);
36 return result;
37}
38
39std::vector<float> GetProperty(const char* name,
40 const std::vector<float>& default_values) {
41 char prop[PROPERTY_VALUE_MAX + 1] = {};
42 property_get(name, prop, "");
43 std::vector<std::string> values = SplitString(prop, ',');
44 std::vector<float> results;
45 for (const auto& value : values) {
46 float result = 0.0f;
47 if (StringToFloat(value.c_str(), &result)) {
48 results.push_back(static_cast<float>(result));
49 }
50 }
51 if (results.empty()) {
52 return default_values;
53 }
54 return results;
55}
56
57float GetProperty(const char* name, float default_value) {
58 char prop[PROPERTY_VALUE_MAX + 1] = {};
59 property_get(name, prop, "");
60 float result = 0.0f;
61 if (StringToFloat(prop, &result)) {
62 return static_cast<float>(result);
63 }
64 return default_value;
65}
66
67float GetInterLensDistance() { return GetProperty(kLensDistance, 0.064f); }
68
69float GetDisplayGap() { return GetProperty(kDisplayGap, 0.0f); }
70
71float GetVEyeToDisplay() { return GetProperty(kVEyeToDisplay, 0.035f); }
72
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 = {
113 -4.08519004f, 34.70282075f, -67.37781249f, 56.97304235f,
114 -23.35768685f, 4.7199597f, 0.63198082f};
115 static const std::vector<float> default_g = {
116 4.43078318f, 3.47806617f, -20.58017398f, 20.85880414f,
117 -8.4046504f, 1.61284685f, 0.8881761f};
118 static const std::vector<float> default_b = {
119 12.04141265f, -21.98112491f, 14.06758389f, -3.15245629f,
120 0.36549102f, 0.05252705f, 0.99844279f};
121 static const std::vector<float> default_offsets = {
122 0.20971645238f, 0.15189450000f, 1.00096958278f};
123
124 std::vector<float> poly_offsets =
125 GetProperty(kRGBPolynomialOffset, default_offsets);
126 std::vector<float> poly_r = GetProperty(kRPolynomial, default_r);
127 std::vector<float> poly_g = GetProperty(kGPolynomial, default_g);
128 std::vector<float> poly_b = GetProperty(kBPolynomial, default_b);
129 if (poly_offsets.size() != 3)
130 poly_offsets = default_offsets;
131
132 std::shared_ptr<ColorChannelDistortion> distortion_r(
133 new PolynomialRadialDistortion(poly_offsets[0], poly_r));
134 std::shared_ptr<ColorChannelDistortion> distortion_g(
135 new PolynomialRadialDistortion(poly_offsets[1], poly_g));
136 std::shared_ptr<ColorChannelDistortion> distortion_b(
137 new PolynomialRadialDistortion(poly_offsets[2], poly_b));
138
139 return HeadMountMetrics(GetInterLensDistance(), GetVEyeToDisplay(),
140 GetVEyeToDisplay(), kDefaultVerticalAlignment, l_fov,
141 r_fov, distortion_r, distortion_g, distortion_b,
142 HeadMountMetrics::EyeOrientation::kCCW0Degrees,
143 HeadMountMetrics::EyeOrientation::kCCW0Degrees,
144 (GetInterLensDistance() - GetDisplayGap()) / 2.0f);
145}
146
147HeadMountMetrics CreateHeadMountMetrics() {
148 std::vector<float> fovs = GetMaxFOVs();
149 FieldOfView l_fov(fovs[1], fovs[0], fovs[2], fovs[3]);
150 FieldOfView r_fov(fovs[0], fovs[1], fovs[2], fovs[3]);
151 return CreateHeadMountMetrics(l_fov, r_fov);
152}
153
154DisplayMetrics CreateDisplayMetrics(vec2i screen_size) {
155 android::dvr::vec2 size_in_meters = GetDisplaySize();
156 vec2 meters_per_pixel(size_in_meters[0] / static_cast<float>(screen_size[0]),
157 size_in_meters[1] / static_cast<float>(screen_size[1]));
158 return DisplayMetrics(screen_size, meters_per_pixel, kScreenBorderSize,
159 1000.0f / kScreenRefreshRate, kDisplayOrientation);
160}
161
162HeadMountMetrics CreateUndistortedHeadMountMetrics() {
163 std::vector<float> fovs = GetMaxFOVs();
164 FieldOfView l_fov(fovs[1], fovs[0], fovs[2], fovs[3]);
165 FieldOfView r_fov(fovs[0], fovs[1], fovs[2], fovs[3]);
166 return CreateUndistortedHeadMountMetrics(l_fov, r_fov);
167}
168
169HeadMountMetrics CreateUndistortedHeadMountMetrics(const FieldOfView& l_fov,
170 const FieldOfView& r_fov) {
171 auto distortion_all = std::make_shared<IdentityDistortion>();
172
173 return HeadMountMetrics(GetInterLensDistance(), GetVEyeToDisplay(),
174 GetVEyeToDisplay(), kDefaultVerticalAlignment, l_fov,
175 r_fov, distortion_all, distortion_all, distortion_all,
176 HeadMountMetrics::EyeOrientation::kCCW0Degrees,
177 HeadMountMetrics::EyeOrientation::kCCW0Degrees,
178 (GetInterLensDistance() - GetDisplayGap()) / 2.0f);
179}
180
181} // namespace dvr
182} // namespace android