Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: chrome/browser/android/vr_shell/vr_shell.cc

Issue 2301633002: Refactor Vr activity into ChromeTabbedActivity. (Closed)
Patch Set: Address comments and rebase Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/android/vr_shell/vr_shell.h" 5 #include "chrome/browser/android/vr_shell/vr_shell.h"
6 6
7 #include <thread>
8
7 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h" 9 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h"
8 #include "chrome/browser/android/vr_shell/vr_util.h" 10 #include "chrome/browser/android/vr_shell/vr_util.h"
9 #include "jni/VrShell_jni.h" 11 #include "jni/VrShell_jni.h"
10 #include "ui/gl/gl_bindings.h" 12 #include "ui/gl/gl_bindings.h"
11 #include "ui/gl/init/gl_factory.h" 13 #include "ui/gl/init/gl_factory.h"
12 14
13 namespace vr_shell { 15 using base::android::JavaParamRef;
14 16
15 namespace { 17 namespace {
16 // Constant taken from treasure_hunt demo. 18 // Constant taken from treasure_hunt demo.
17 const long kPredictionTimeWithoutVsyncNanos = 50000000; 19 static constexpr long kPredictionTimeWithoutVsyncNanos = 50000000;
18 20
19 const float kZNear = 0.1f; 21 static constexpr float kZNear = 0.1f;
20 const float kZFar = 1000.0f; 22 static constexpr float kZFar = 1000.0f;
21 23
22 // Content rect in world coordinates. Height and width are currently supplied 24 static constexpr gvr::Vec3f kDesktopPositionDefault = {0.0f, 0.0f, -2.0f};
23 // as DrawFrame arguments. 25 static constexpr float kDesktopHeightDefault = 1.6f;
24 const gvr::Vec3f kContentRectPositionDefault = {0.0f, 0.0f, -1.0f};
25 26
26 } // namespace 27 // Screen angle in degrees. 0 = vertical, positive = top closer.
28 static constexpr float kDesktopScreenTiltDefault = 0;
27 29
28 ContentRect::ContentRect() { 30 static constexpr float kScreenHeightMeters = 2.0f;
29 SetIdentity(); 31 static constexpr float kScreenWidthMeters = 2.0f;
30 } 32 }
David Trainor- moved to gerrit 2016/09/09 06:28:29 // namespace
mthiesse 2016/09/09 15:16:38 Done.
31 33
32 ContentRect::~ContentRect() {} 34 namespace vr_shell {
33 35
34 void ContentRect::SetIdentity() { 36 VrShell::VrShell(JNIEnv* env, jobject obj)
35 transfrom_to_world.m[0][0] = 1; 37 : desktop_screen_tilt_(kDesktopScreenTiltDefault),
36 transfrom_to_world.m[0][1] = 0; 38 desktop_height_(kDesktopHeightDefault),
37 transfrom_to_world.m[0][2] = 0; 39 desktop_position_(kDesktopPositionDefault) {
38 transfrom_to_world.m[0][3] = 0;
39 transfrom_to_world.m[1][0] = 0;
40 transfrom_to_world.m[1][1] = 1;
41 transfrom_to_world.m[1][2] = 0;
42 transfrom_to_world.m[1][3] = 0;
43 transfrom_to_world.m[2][0] = 0;
44 transfrom_to_world.m[2][1] = 0;
45 transfrom_to_world.m[2][2] = 1;
46 transfrom_to_world.m[2][3] = 0;
47 transfrom_to_world.m[3][0] = 0;
48 transfrom_to_world.m[3][1] = 0;
49 transfrom_to_world.m[3][2] = 0;
50 transfrom_to_world.m[3][3] = 1;
51 }
52
53 void ContentRect::Translate(float x, float y, float z) {
54 transfrom_to_world.m[0][3] += x;
55 transfrom_to_world.m[1][3] += y;
56 transfrom_to_world.m[2][3] += z;
57 }
58
59 VrShell::VrShell(JNIEnv* env, jobject obj) {
60 j_vr_shell_.Reset(env, obj); 40 j_vr_shell_.Reset(env, obj);
41 ui_rects_.emplace_back(new ContentRectangle());
42 desktop_plane_ = ui_rects_.back().get();
43 desktop_plane_->id = 0;
44 desktop_plane_->copy_rect = {0.0f, 0.0f, 1.0f, 1.0f};
45 // TODO(cjgrant): If we use the native path for content clicks, fix this.
46 desktop_plane_->window_rect = {0, 0, 0, 0};
47 desktop_plane_->translation = {0.0f, 0.0f, 0.0f};
48 desktop_plane_->x_anchoring = XNONE;
49 desktop_plane_->y_anchoring = YNONE;
50 desktop_plane_->anchor_z = false;
51 desktop_plane_->orientation_axis_angle = {{1.0f, 0.0f, 0.0f, 0.0f}};
52 desktop_plane_->rotation_axis_angle = {{0.0f, 0.0f, 0.0f, 0.0f}};
61 } 53 }
62 54
63 void VrShell::Destroy(JNIEnv* env, 55 void VrShell::Destroy(JNIEnv* env,
64 const base::android::JavaParamRef<jobject>& obj) { 56 const base::android::JavaParamRef<jobject>& obj) {
bshe 2016/09/09 14:42:10 looks like you missed this one. remove base::andro
mthiesse 2016/09/09 15:16:38 Done.
65 delete this; 57 delete this;
58 gl::init::ClearGLBindings();
66 } 59 }
67 60
68 bool RegisterVrShell(JNIEnv* env) { 61 bool RegisterVrShell(JNIEnv* env) {
69 return RegisterNativesImpl(env); 62 return RegisterNativesImpl(env);
70 } 63 }
71 64
72 VrShell::~VrShell() {} 65 VrShell::~VrShell() {}
73 66
74 void VrShell::GvrInit(JNIEnv* env, 67 void VrShell::GvrInit(JNIEnv* env,
75 const base::android::JavaParamRef<jobject>& obj, 68 const JavaParamRef<jobject>& obj,
76 jlong native_gvr_api) { 69 jlong native_gvr_api) {
77 gvr_api_ = 70 gvr_api_ =
78 gvr::GvrApi::WrapNonOwned(reinterpret_cast<gvr_context*>(native_gvr_api)); 71 gvr::GvrApi::WrapNonOwned(reinterpret_cast<gvr_context*>(native_gvr_api));
79 } 72 }
80 73
81 void VrShell::InitializeGl(JNIEnv* env, 74 void VrShell::InitializeGl(JNIEnv* env,
82 const base::android::JavaParamRef<jobject>& obj, 75 const JavaParamRef<jobject>& obj,
83 jint texture_data_handle) { 76 jint texture_data_handle) {
84 gl::init::InitializeGLOneOff(); 77 CHECK(gl::GetGLImplementation() != gl::kGLImplementationNone ||
78 gl::init::InitializeGLOneOff());
79
80 content_texture_id_ = texture_data_handle;
85 gvr_api_->InitializeGl(); 81 gvr_api_->InitializeGl();
86 std::vector<gvr::BufferSpec> specs; 82 std::vector<gvr::BufferSpec> specs;
87 specs.push_back(gvr_api_->CreateBufferSpec()); 83 specs.push_back(gvr_api_->CreateBufferSpec());
88 render_size_ = specs[0].GetSize(); 84 render_size_ = specs[0].GetSize();
89 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapchain(specs))); 85 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapchain(specs)));
90 content_rect_.reset(new ContentRect()); 86
91 content_rect_->content_texture_handle = 87 desktop_plane_->content_texture_handle = content_texture_id_;
92 reinterpret_cast<int>(texture_data_handle); 88
93 vr_shell_renderer_.reset(new VrShellRenderer()); 89 vr_shell_renderer_.reset(new VrShellRenderer());
94 buffer_viewport_list_.reset( 90 buffer_viewport_list_.reset(
95 new gvr::BufferViewportList(gvr_api_->CreateEmptyBufferViewportList())); 91 new gvr::BufferViewportList(gvr_api_->CreateEmptyBufferViewportList()));
96 buffer_viewport_.reset( 92 buffer_viewport_.reset(
97 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); 93 new gvr::BufferViewport(gvr_api_->CreateBufferViewport()));
98 } 94 }
99 95
96 void ApplyNeckModel(gvr::Mat4f& mat_forward) {
97 // This assumes that the input matrix is a pure rotation matrix. The
98 // input object_from_reference matrix has the inverse rotation of
99 // the head rotation. Invert it (this is just a transpose).
100 gvr::Mat4f mat = MatrixTranspose(mat_forward);
101
102 // Position of the point between the eyes, relative to the neck pivot:
103 const float kNeckHorizontalOffset = -0.080f; // meters in Z
104 const float kNeckVerticalOffset = 0.075f; // meters in Y
105
106 std::array<float, 4> neckOffset = {
107 {0.0f, kNeckVerticalOffset, kNeckHorizontalOffset, 1.0f}};
108
109 // Rotate eyes around neck pivot point.
110 auto offset = MatrixVectorMul(mat, neckOffset);
111
112 // Measure new position relative to original center of head, because
113 // applying a neck model should not elevate the camera.
114 offset[1] -= kNeckVerticalOffset;
115
116 // Right-multiply the inverse translation onto the
117 // object_from_reference_matrix.
118 TranslateMRight(mat_forward, mat_forward, -offset[0], -offset[1], -offset[2]);
119 }
120
100 void VrShell::DrawFrame(JNIEnv* env, 121 void VrShell::DrawFrame(JNIEnv* env,
101 const base::android::JavaParamRef<jobject>& obj) { 122 const JavaParamRef<jobject>& obj) {
123 float screen_width = kScreenWidthMeters * desktop_height_;
124 float screen_height = kScreenHeightMeters * desktop_height_;
125
126 float screen_tilt = desktop_screen_tilt_ * M_PI / 180.0f;
127
102 buffer_viewport_list_->SetToRecommendedBufferViewports(); 128 buffer_viewport_list_->SetToRecommendedBufferViewports();
129
103 gvr::Frame frame = swap_chain_->AcquireFrame(); 130 gvr::Frame frame = swap_chain_->AcquireFrame();
104 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); 131 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow();
105 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; 132 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos;
106 head_pose_ = gvr_api_->GetHeadPoseInStartSpace(target_time); 133 head_pose_ = gvr_api_->GetHeadPoseInStartSpace(target_time);
107 134
108 // Content area positioning. 135 gvr::Vec3f headPos = getTranslation(head_pose_);
109 content_rect_->SetIdentity(); 136 if (headPos.x == 0.0f && headPos.y == 0.0f && headPos.z == 0.0f) {
110 content_rect_->Translate(kContentRectPositionDefault.x, 137 // This appears to be a 3DOF pose without a neck model. Add one.
111 kContentRectPositionDefault.y, 138 // The head pose has redundant data. Assume we're only using the
112 kContentRectPositionDefault.z); 139 // object_from_reference_matrix, we're not updating position_external.
140 // TODO: Not sure what object_from_reference_matrix is. The new api removed
141 // it. For now, removing it seems working fine.
142 ApplyNeckModel(head_pose_);
143 }
113 144
145 desktop_plane_->size = {screen_width, screen_height, 1.0f};
146 desktop_plane_->translation.x = desktop_position_.x;
147 desktop_plane_->translation.y = desktop_position_.y;
148 desktop_plane_->translation.z = desktop_position_.z;
149
150 // Update position of all UI elements (including desktop)
151 UpdateTransforms(screen_width, screen_height, screen_tilt);
152
153 // Everything should be positioned now, ready for drawing.
114 gvr::Mat4f left_eye_view_matrix = 154 gvr::Mat4f left_eye_view_matrix =
115 MatrixMul(gvr_api_->GetEyeFromHeadMatrix(GVR_LEFT_EYE), head_pose_); 155 MatrixMul(gvr_api_->GetEyeFromHeadMatrix(GVR_LEFT_EYE), head_pose_);
116 gvr::Mat4f right_eye_view_matrix = 156 gvr::Mat4f right_eye_view_matrix =
117 MatrixMul(gvr_api_->GetEyeFromHeadMatrix(GVR_RIGHT_EYE), head_pose_); 157 MatrixMul(gvr_api_->GetEyeFromHeadMatrix(GVR_RIGHT_EYE), head_pose_);
118 158
119 // Bind back to the default framebuffer. 159 // Bind back to the default framebuffer.
120 frame.BindBuffer(0); 160 frame.BindBuffer(0);
121 161
122 // Use culling to remove back faces. 162 // Use culling to remove back faces.
123 glEnable(GL_CULL_FACE); 163 glEnable(GL_CULL_FACE);
124 164
125 // Enable depth testing. 165 // Enable depth testing.
126 glEnable(GL_DEPTH_TEST); 166 glEnable(GL_DEPTH_TEST);
127 glEnable(GL_SCISSOR_TEST); 167 glEnable(GL_SCISSOR_TEST);
128 168
129 glClearColor(0.1f, 0.1f, 0.1f, 1.0f); 169 glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
130 170
131 // Enable transparency.
132 glEnable(GL_BLEND);
133 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
134
135 buffer_viewport_list_->GetBufferViewport(GVR_LEFT_EYE, 171 buffer_viewport_list_->GetBufferViewport(GVR_LEFT_EYE,
136 buffer_viewport_.get()); 172 buffer_viewport_.get());
137 DrawEye(left_eye_view_matrix, *buffer_viewport_); 173 DrawEye(left_eye_view_matrix, *buffer_viewport_);
138 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE, 174 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE,
139 buffer_viewport_.get()); 175 buffer_viewport_.get());
140 DrawEye(right_eye_view_matrix, *buffer_viewport_); 176 DrawEye(right_eye_view_matrix, *buffer_viewport_);
141 177
142 frame.Unbind(); 178 frame.Unbind();
143 frame.Submit(*buffer_viewport_list_, head_pose_); 179 frame.Submit(*buffer_viewport_list_, head_pose_);
144 } 180 }
145 181
146 void VrShell::DrawEye(const gvr::Mat4f& view_matrix, 182 void VrShell::DrawEye(const gvr::Mat4f& view_matrix,
147 const gvr::BufferViewport& params) { 183 const gvr::BufferViewport& params) {
148 gvr::Recti pixel_rect = 184 gvr::Recti pixel_rect =
149 CalculatePixelSpaceRect(render_size_, params.GetSourceUv()); 185 CalculatePixelSpaceRect(render_size_, params.GetSourceUv());
150 glViewport(pixel_rect.left, pixel_rect.bottom, 186 glViewport(pixel_rect.left, pixel_rect.bottom,
151 pixel_rect.right - pixel_rect.left, 187 pixel_rect.right - pixel_rect.left,
152 pixel_rect.top - pixel_rect.bottom); 188 pixel_rect.top - pixel_rect.bottom);
153 glScissor(pixel_rect.left, pixel_rect.bottom, 189 glScissor(pixel_rect.left, pixel_rect.bottom,
154 pixel_rect.right - pixel_rect.left, 190 pixel_rect.right - pixel_rect.left,
155 pixel_rect.top - pixel_rect.bottom); 191 pixel_rect.top - pixel_rect.bottom);
156 192
157 view_matrix_ = view_matrix; 193 view_matrix_ = view_matrix;
158 194
159 projection_matrix_ = 195 projection_matrix_ =
160 PerspectiveMatrixFromView(params.GetSourceFov(), kZNear, kZFar); 196 PerspectiveMatrixFromView(params.GetSourceFov(), kZNear, kZFar);
161 197
162 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 198 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
163 DrawContentRect(); 199 DrawUI();
164 } 200 }
165 201
166 void VrShell::DrawContentRect() { 202 void VrShell::DrawUI() {
167 gvr::Mat4f content_rect_combined_matrix = 203 for (std::size_t i = 0; i < ui_rects_.size(); ++i) {
168 MatrixMul(view_matrix_, content_rect_->transfrom_to_world); 204 gvr::Mat4f combined_matrix =
169 content_rect_combined_matrix = 205 MatrixMul(view_matrix_, ui_rects_[i].get()->transform_.to_world_);
170 MatrixMul(projection_matrix_, content_rect_combined_matrix); 206 combined_matrix = MatrixMul(projection_matrix_, combined_matrix);
171 vr_shell_renderer_->GetTexturedQuadRenderer()->Draw( 207 vr_shell_renderer_->GetTexturedQuadRenderer()->Draw(
172 content_rect_->content_texture_handle, content_rect_combined_matrix); 208 ui_rects_[i].get()->content_texture_handle, combined_matrix,
209 ui_rects_[i].get()->copy_rect);
210 }
173 } 211 }
174 212
175 void VrShell::OnPause(JNIEnv* env, 213 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) {
176 const base::android::JavaParamRef<jobject>& obj) {
177 if (gvr_api_ == nullptr) 214 if (gvr_api_ == nullptr)
178 return; 215 return;
179 gvr_api_->PauseTracking(); 216 gvr_api_->PauseTracking();
180 } 217 }
181 218
182 void VrShell::OnResume(JNIEnv* env, 219 void VrShell::OnResume(JNIEnv* env, const JavaParamRef<jobject>& obj) {
183 const base::android::JavaParamRef<jobject>& obj) {
184 if (gvr_api_ == nullptr) 220 if (gvr_api_ == nullptr)
185 return; 221 return;
222
186 gvr_api_->RefreshViewerProfile(); 223 gvr_api_->RefreshViewerProfile();
187 gvr_api_->ResumeTracking(); 224 gvr_api_->ResumeTracking();
188 } 225 }
189 226
227 void VrShell::UpdateTransforms(float screen_width_meters,
228 float screen_height_meters,
229 float screen_tilt) {
230 for (std::unique_ptr<ContentRectangle>& rect : ui_rects_) {
231 rect->transform_.MakeIdentity();
232 rect->transform_.Scale(rect->size.x, rect->size.y, rect->size.z);
233 float x_anchor_translate;
234 switch (rect->x_anchoring) {
235 case XLEFT:
236 x_anchor_translate = desktop_position_.x - screen_width_meters * 0.5;
237 break;
238 case XRIGHT:
239 x_anchor_translate = desktop_position_.x + screen_width_meters * 0.5;
240 break;
241 case XCENTER:
242 x_anchor_translate = desktop_position_.x;
243 break;
244 case XNONE:
245 x_anchor_translate = 0;
246 break;
247 }
248 float y_anchor_translate;
249 switch (rect->y_anchoring) {
250 case YTOP:
251 y_anchor_translate = desktop_position_.y + screen_height_meters * 0.5;
252 break;
253 case YBOTTOM:
254 y_anchor_translate = desktop_position_.y - screen_height_meters * 0.5;
255 break;
256 case YCENTER:
257 y_anchor_translate = desktop_position_.y;
258 break;
259 case YNONE:
260 y_anchor_translate = 0;
261 break;
262 }
263 float zAnchorTranslate = rect->anchor_z ? desktop_position_.z : 0;
bshe 2016/09/09 14:42:10 nit: z_anchor_translate
mthiesse 2016/09/09 15:16:38 Done.
264 rect->transform_.Translate(x_anchor_translate + rect->translation.x,
265 y_anchor_translate + rect->translation.y,
266 zAnchorTranslate + rect->translation.z);
267 // TODO(cjgrant): Establish which exact rotations we'll provide.
268 // Adjust for screen tilt.
269 rect->transform_.Rotate(1.0f, 0.0f, 0.0f, screen_tilt);
270 }
271 }
272
190 // ---------------------------------------------------------------------------- 273 // ----------------------------------------------------------------------------
191 // Native JNI methods 274 // Native JNI methods
192 // ---------------------------------------------------------------------------- 275 // ----------------------------------------------------------------------------
193 276
194 jlong Init(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj) { 277 jlong Init(JNIEnv* env, const JavaParamRef<jobject>& obj) {
195 VrShell* vrShell = new VrShell(env, obj); 278 return reinterpret_cast<intptr_t>(new VrShell(env, obj));
196 return reinterpret_cast<intptr_t>(vrShell);
197 } 279 }
198 280
199 } // namespace vr_shell 281 } // namespace vr_shell
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698