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

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

Issue 2739973002: Revert of WebVR compositor bypass via BrowserMain context + mailbox (Closed)
Patch Set: Created 3 years, 9 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_gl.h" 5 #include "chrome/browser/android/vr_shell/vr_shell_gl.h"
6 6
7 #include <limits> 7 #include <limits>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/android/jni_android.h" 10 #include "base/android/jni_android.h"
11 #include "base/callback_helpers.h" 11 #include "base/callback_helpers.h"
12 #include "base/memory/ptr_util.h" 12 #include "base/memory/ptr_util.h"
13 #include "base/metrics/histogram_macros.h" 13 #include "base/metrics/histogram_macros.h"
14 #include "base/threading/thread_task_runner_handle.h" 14 #include "base/threading/thread_task_runner_handle.h"
15 #include "chrome/browser/android/vr_shell/mailbox_to_surface_bridge.h"
16 #include "chrome/browser/android/vr_shell/ui_elements.h" 15 #include "chrome/browser/android/vr_shell/ui_elements.h"
17 #include "chrome/browser/android/vr_shell/ui_scene.h" 16 #include "chrome/browser/android/vr_shell/ui_scene.h"
18 #include "chrome/browser/android/vr_shell/vr_controller.h" 17 #include "chrome/browser/android/vr_shell/vr_controller.h"
19 #include "chrome/browser/android/vr_shell/vr_gl_util.h" 18 #include "chrome/browser/android/vr_shell/vr_gl_util.h"
20 #include "chrome/browser/android/vr_shell/vr_math.h" 19 #include "chrome/browser/android/vr_shell/vr_math.h"
21 #include "chrome/browser/android/vr_shell/vr_shell.h" 20 #include "chrome/browser/android/vr_shell/vr_shell.h"
22 #include "chrome/browser/android/vr_shell/vr_shell_delegate.h" 21 #include "chrome/browser/android/vr_shell/vr_shell_delegate.h"
23 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h" 22 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h"
24 #include "device/vr/android/gvr/gvr_device.h" 23 #include "device/vr/android/gvr/gvr_device.h"
25 #include "third_party/WebKit/public/platform/WebInputEvent.h" 24 #include "third_party/WebKit/public/platform/WebInputEvent.h"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 73
75 // The GVR viewport list has two entries (left eye and right eye) for each 74 // The GVR viewport list has two entries (left eye and right eye) for each
76 // GVR buffer. 75 // GVR buffer.
77 static constexpr int kViewportListPrimaryOffset = 0; 76 static constexpr int kViewportListPrimaryOffset = 0;
78 static constexpr int kViewportListHeadlockedOffset = 2; 77 static constexpr int kViewportListHeadlockedOffset = 2;
79 78
80 // Buffer size large enough to handle the current backlog of poses which is 79 // Buffer size large enough to handle the current backlog of poses which is
81 // 2-3 frames. 80 // 2-3 frames.
82 static constexpr unsigned kPoseRingBufferSize = 8; 81 static constexpr unsigned kPoseRingBufferSize = 8;
83 82
84 // Default downscale factor for computing the recommended WebVR 83 // Magic numbers used to mark valid pose index values encoded in frame
85 // renderWidth/Height from the 1:1 pixel mapped size. Using a rather 84 // data. Must match the magic numbers used in blink's VRDisplay.cpp.
86 // aggressive downscale due to the high overhead of copying pixels 85 static constexpr std::array<uint8_t, 2> kWebVrPosePixelMagicNumbers{{42, 142}};
87 // twice before handing off to GVR. For comparison, the polyfill
88 // uses approximately 0.55 on a Pixel XL.
89 static constexpr float kWebVrRecommendedResolutionScale = 0.5;
90 86
91 float Distance(const gvr::Vec3f& vec1, const gvr::Vec3f& vec2) { 87 float Distance(const gvr::Vec3f& vec1, const gvr::Vec3f& vec2) {
92 float xdiff = (vec1.x - vec2.x); 88 float xdiff = (vec1.x - vec2.x);
93 float ydiff = (vec1.y - vec2.y); 89 float ydiff = (vec1.y - vec2.y);
94 float zdiff = (vec1.z - vec2.z); 90 float zdiff = (vec1.z - vec2.z);
95 float scale = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff; 91 float scale = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff;
96 return std::sqrt(scale); 92 return std::sqrt(scale);
97 } 93 }
98 94
99 // Generate a quaternion representing the rotation from the negative Z axis 95 // Generate a quaternion representing the rotation from the negative Z axis
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 binding_(this), 165 binding_(this),
170 weak_vr_shell_(weak_vr_shell), 166 weak_vr_shell_(weak_vr_shell),
171 delegate_provider_(delegate_provider), 167 delegate_provider_(delegate_provider),
172 main_thread_task_runner_(std::move(main_thread_task_runner)), 168 main_thread_task_runner_(std::move(main_thread_task_runner)),
173 weak_ptr_factory_(this) { 169 weak_ptr_factory_(this) {
174 GvrInit(gvr_api); 170 GvrInit(gvr_api);
175 } 171 }
176 172
177 VrShellGl::~VrShellGl() { 173 VrShellGl::~VrShellGl() {
178 vsync_task_.Cancel(); 174 vsync_task_.Cancel();
179 // TODO(mthiesse): Can we omit the Close() here? Concern is that if
180 // both ends of the connection ever live in the same process for
181 // some reason, we could receive another VSync request in response
182 // to the closing message in the destructor but fail to respond to
183 // the callback.
184 binding_.Close();
185 if (!callback_.is_null()) { 175 if (!callback_.is_null()) {
186 // When this VSync provider is going away we have to respond to pending 176 // When this VSync provider is going away we have to respond to pending
187 // callbacks, so instead of providing a VSync, tell the requester to try 177 // callbacks, so instead of providing a VSync, tell the requester to try
188 // again. A VSyncProvider is guaranteed to exist, so the request in response 178 // again. A VSyncProvider is guaranteed to exist, so the request in response
189 // to this message will go through some other VSyncProvider. 179 // to this message will go through some other VSyncProvider.
190 base::ResetAndReturn(&callback_) 180 base::ResetAndReturn(&callback_)
191 .Run(nullptr, base::TimeDelta(), -1, 181 .Run(nullptr, base::TimeDelta(), -1,
192 device::mojom::VRVSyncProvider::Status::CLOSING); 182 device::mojom::VRVSyncProvider::Status::RETRY);
183 }
184 if (binding_.is_bound()) {
185 main_thread_task_runner_->PostTask(
186 FROM_HERE,
187 base::Bind(&VrShellDelegate::OnVRVsyncProviderRequest,
188 delegate_provider_, base::Passed(binding_.Unbind())));
193 } 189 }
194 } 190 }
195 191
196 void VrShellGl::Initialize() { 192 void VrShellGl::Initialize() {
197 scene_.reset(new UiScene); 193 scene_.reset(new UiScene);
198 194
199 if (surfaceless_rendering_) { 195 if (surfaceless_rendering_) {
200 // If we're rendering surfaceless, we'll never get a java surface to render 196 // If we're rendering surfaceless, we'll never get a java surface to render
201 // into, so we can initialize GL right away. 197 // into, so we can initialize GL right away.
202 InitializeGl(nullptr); 198 InitializeGl(nullptr);
(...skipping 26 matching lines...) Expand all
229 LOG(ERROR) << "gl::init::CreateGLContext failed"; 225 LOG(ERROR) << "gl::init::CreateGLContext failed";
230 ForceExitVr(); 226 ForceExitVr();
231 return; 227 return;
232 } 228 }
233 if (!context_->MakeCurrent(surface_.get())) { 229 if (!context_->MakeCurrent(surface_.get())) {
234 LOG(ERROR) << "gl::GLContext::MakeCurrent() failed"; 230 LOG(ERROR) << "gl::GLContext::MakeCurrent() failed";
235 ForceExitVr(); 231 ForceExitVr();
236 return; 232 return;
237 } 233 }
238 234
239 unsigned int textures[3]; 235 unsigned int textures[2];
240 glGenTextures(3, textures); 236 glGenTextures(2, textures);
241 ui_texture_id_ = textures[0]; 237 ui_texture_id_ = textures[0];
242 content_texture_id_ = textures[1]; 238 content_texture_id_ = textures[1];
243 webvr_texture_id_ = textures[2];
244 ui_surface_texture_ = gl::SurfaceTexture::Create(ui_texture_id_); 239 ui_surface_texture_ = gl::SurfaceTexture::Create(ui_texture_id_);
245 content_surface_texture_ = gl::SurfaceTexture::Create(content_texture_id_); 240 content_surface_texture_ = gl::SurfaceTexture::Create(content_texture_id_);
246 webvr_surface_texture_ = gl::SurfaceTexture::Create(webvr_texture_id_);
247 CreateUiSurface(); 241 CreateUiSurface();
248 CreateContentSurface(); 242 CreateContentSurface();
249 ui_surface_texture_->SetFrameAvailableCallback(base::Bind( 243 ui_surface_texture_->SetFrameAvailableCallback(base::Bind(
250 &VrShellGl::OnUIFrameAvailable, weak_ptr_factory_.GetWeakPtr())); 244 &VrShellGl::OnUIFrameAvailable, weak_ptr_factory_.GetWeakPtr()));
251 content_surface_texture_->SetFrameAvailableCallback(base::Bind( 245 content_surface_texture_->SetFrameAvailableCallback(base::Bind(
252 &VrShellGl::OnContentFrameAvailable, weak_ptr_factory_.GetWeakPtr())); 246 &VrShellGl::OnContentFrameAvailable, weak_ptr_factory_.GetWeakPtr()));
253 webvr_surface_texture_->SetFrameAvailableCallback(base::Bind( 247 content_surface_texture_->SetDefaultBufferSize(
254 &VrShellGl::OnWebVRFrameAvailable, weak_ptr_factory_.GetWeakPtr())); 248 content_tex_physical_size_.width, content_tex_physical_size_.height);
255 ui_surface_texture_->SetDefaultBufferSize(ui_tex_physical_size_.width, 249 ui_surface_texture_->SetDefaultBufferSize(ui_tex_physical_size_.width,
256 ui_tex_physical_size_.height); 250 ui_tex_physical_size_.height);
257 content_surface_texture_->SetDefaultBufferSize(
258 content_tex_physical_size_.width, content_tex_physical_size_.height);
259 InitializeRenderer(); 251 InitializeRenderer();
260 252
261 // Pick a reasonable default size for the WebVR transfer surface
262 // based on a downscaled 1:1 render resolution. This size will also
263 // be reported to the client via CreateVRDisplayInfo as the
264 // client-recommended renderWidth/renderHeight and for the GVR
265 // framebuffer. If the client chooses a different size or resizes it
266 // while presenting, we'll resize the transfer surface and GVR
267 // framebuffer to match.
268 gvr::Sizei render_target_size =
269 gvr_api_->GetMaximumEffectiveRenderTargetSize();
270 gvr::Sizei webvr_size = {static_cast<int>(render_target_size.width *
271 kWebVrRecommendedResolutionScale),
272 static_cast<int>(render_target_size.height *
273 kWebVrRecommendedResolutionScale)};
274
275 // TODO(klausw,crbug.com/699350): should we round the recommended
276 // size to a multiple of 2^N pixels to be friendlier to the GPU? The
277 // exact size doesn't matter.
278
279 CreateOrResizeWebVRSurface(webvr_size);
280
281 vsync_task_.Reset(base::Bind(&VrShellGl::OnVSync, base::Unretained(this))); 253 vsync_task_.Reset(base::Bind(&VrShellGl::OnVSync, base::Unretained(this)));
282 OnVSync(); 254 OnVSync();
283 255
284 ready_to_draw_ = true; 256 ready_to_draw_ = true;
285 } 257 }
286 258
287 void VrShellGl::CreateContentSurface() { 259 void VrShellGl::CreateContentSurface() {
288 content_surface_ = 260 content_surface_ =
289 base::MakeUnique<gl::ScopedJavaSurface>(content_surface_texture_.get()); 261 base::MakeUnique<gl::ScopedJavaSurface>(content_surface_texture_.get());
290 main_thread_task_runner_->PostTask( 262 main_thread_task_runner_->PostTask(
291 FROM_HERE, base::Bind(&VrShell::ContentSurfaceChanged, weak_vr_shell_, 263 FROM_HERE, base::Bind(&VrShell::ContentSurfaceChanged, weak_vr_shell_,
292 content_surface_->j_surface().obj())); 264 content_surface_->j_surface().obj()));
293 } 265 }
294 266
295 void VrShellGl::CreateUiSurface() { 267 void VrShellGl::CreateUiSurface() {
296 ui_surface_ = 268 ui_surface_ =
297 base::MakeUnique<gl::ScopedJavaSurface>(ui_surface_texture_.get()); 269 base::MakeUnique<gl::ScopedJavaSurface>(ui_surface_texture_.get());
298 main_thread_task_runner_->PostTask( 270 main_thread_task_runner_->PostTask(
299 FROM_HERE, base::Bind(&VrShell::UiSurfaceChanged, weak_vr_shell_, 271 FROM_HERE, base::Bind(&VrShell::UiSurfaceChanged, weak_vr_shell_,
300 ui_surface_->j_surface().obj())); 272 ui_surface_->j_surface().obj()));
301 } 273 }
302 274
303 void VrShellGl::CreateOrResizeWebVRSurface(const gvr::Sizei& size) {
304 if (!webvr_surface_texture_) {
305 DLOG(ERROR) << "No WebVR surface texture available";
306 return;
307 }
308
309 // ContentPhysicalBoundsChanged is getting called twice with
310 // identical sizes? Avoid thrashing the existing context.
311 if (size == webvr_surface_size_) {
312 return;
313 }
314
315 if (!size.width || !size.height) {
316 // Invalid size, defer until a new size arrives on a future bounds update.
317 return;
318 }
319
320 webvr_surface_texture_->SetDefaultBufferSize(size.width, size.height);
321 webvr_surface_size_ = size;
322
323 if (mailbox_bridge_) {
324 mailbox_bridge_->ResizeSurface(size.width, size.height);
325 } else {
326 mailbox_bridge_ = base::MakeUnique<MailboxToSurfaceBridge>();
327 mailbox_bridge_->CreateSurface(webvr_surface_texture_.get());
328 }
329 }
330
331 void VrShellGl::SubmitWebVRFrame(int16_t frame_index,
332 const gpu::MailboxHolder& mailbox) {
333 TRACE_EVENT0("gpu", "VrShellGl::SubmitWebVRFrame");
334
335 // Swapping twice on a Surface without calling updateTexImage in
336 // between can lose frames, so don't draw+swap if we already have
337 // a pending frame we haven't consumed yet.
338 bool swapped = false;
339 if (pending_frames_.empty()) {
340 swapped = mailbox_bridge_->CopyMailboxToSurfaceAndSwap(mailbox);
341 if (swapped) {
342 // Tell OnWebVRFrameAvailable to expect a new frame to arrive on
343 // the SurfaceTexture, and save the associated frame index.
344 pending_frames_.emplace(frame_index);
345 }
346 }
347 // Always notify the client that we're done with the mailbox even
348 // if we haven't drawn it, so that it's eligible for destruction.
349 submit_client_->OnSubmitFrameTransferred();
350 if (!swapped) {
351 // We dropped without drawing, report this as completed rendering
352 // now to unblock the client. We're not going to receive it in
353 // OnWebVRFrameAvailable where we'd normally report that.
354 submit_client_->OnSubmitFrameRendered();
355 }
356
357 TRACE_EVENT0("gpu", "VrShellGl::glFinish");
358 // This is a load-bearing glFinish, please don't remove it without
359 // before/after timing comparisons. Goal is to clear the GPU queue
360 // of the native GL context to avoid stalls later in GVR frame
361 // acquire/submit.
362 glFinish();
363 }
364
365 void VrShellGl::SetSubmitClient(
366 device::mojom::VRSubmitFrameClientPtrInfo submit_client_info) {
367 submit_client_.Bind(std::move(submit_client_info));
368 }
369
370 void VrShellGl::OnUIFrameAvailable() { 275 void VrShellGl::OnUIFrameAvailable() {
371 ui_surface_texture_->UpdateTexImage(); 276 ui_surface_texture_->UpdateTexImage();
372 } 277 }
373 278
374 void VrShellGl::OnContentFrameAvailable() { 279 void VrShellGl::OnContentFrameAvailable() {
375 content_surface_texture_->UpdateTexImage(); 280 content_surface_texture_->UpdateTexImage();
376 received_frame_ = true; 281 received_frame_ = true;
377 } 282 }
378 283
379 void VrShellGl::OnWebVRFrameAvailable() { 284 bool VrShellGl::GetPixelEncodedFrameIndex(uint16_t* frame_index) {
380 // A "while" loop here is a bad idea. It's legal to call 285 TRACE_EVENT0("gpu", "VrShellGl::GetPixelEncodedFrameIndex");
381 // UpdateTexImage repeatedly even if no frames are available, but 286 if (!received_frame_) {
382 // that does *not* wait for a new frame, it just reuses the most 287 if (last_frame_index_ == (uint16_t)-1)
383 // recent one. That would mess up the count. 288 return false;
384 if (pending_frames_.empty()) { 289 *frame_index = last_frame_index_;
385 // We're expecting a frame, but it's not here yet. Retry in OnVsync. 290 return true;
386 ++premature_received_frames_;
387 return;
388 } 291 }
292 received_frame_ = false;
389 293
390 webvr_surface_texture_->UpdateTexImage(); 294 // Read the pose index encoded in a bottom left pixel as color values.
391 int frame_index = pending_frames_.front(); 295 // See also third_party/WebKit/Source/modules/vr/VRDisplay.cpp which
392 TRACE_EVENT1("gpu", "VrShellGl::OnWebVRFrameAvailable", "frame", frame_index); 296 // encodes the pose index, and device/vr/android/gvr/gvr_device.cc
393 pending_frames_.pop(); 297 // which tracks poses. Returns the low byte (0..255) if valid, or -1
298 // if not valid due to bad magic number.
299 uint8_t pixels[4];
300 // Assume we're reading from the framebuffer we just wrote to.
301 // That's true currently, we may need to use glReadBuffer(GL_BACK)
302 // or equivalent if the rendering setup changes in the future.
303 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
394 304
395 // It is legal for the WebVR client to submit a new frame now, since 305 // Check for the magic number written by VRDevice.cpp on submit.
396 // we've consumed the image. TODO(klausw): would timing be better if 306 // This helps avoid glitches from garbage data in the render
397 // we move the "rendered" notification after draw, or suppress 307 // buffer that can appear during initialization or resizing. These
398 // the next vsync until that's done? 308 // often appear as flashes of all-black or all-white pixels.
399 309 if (pixels[1] == kWebVrPosePixelMagicNumbers[0] &&
400 submit_client_->OnSubmitFrameRendered(); 310 pixels[2] == kWebVrPosePixelMagicNumbers[1]) {
401 311 // Pose is good.
402 DrawFrame(frame_index); 312 *frame_index = pixels[0];
313 last_frame_index_ = pixels[0];
314 return true;
315 }
316 VLOG(1) << "WebVR: reject decoded pose index " << static_cast<int>(pixels[0])
317 << ", bad magic number " << static_cast<int>(pixels[1]) << ", "
318 << static_cast<int>(pixels[2]);
319 return false;
403 } 320 }
404 321
405 void VrShellGl::GvrInit(gvr_context* gvr_api) { 322 void VrShellGl::GvrInit(gvr_context* gvr_api) {
406 gvr_api_ = gvr::GvrApi::WrapNonOwned(gvr_api); 323 gvr_api_ = gvr::GvrApi::WrapNonOwned(gvr_api);
407 controller_.reset(new VrController(gvr_api)); 324 controller_.reset(new VrController(gvr_api));
408 325
409 ViewerType viewerType; 326 ViewerType viewerType;
410 switch (gvr_api_->GetViewerType()) { 327 switch (gvr_api_->GetViewerType()) {
411 case gvr::ViewerType::GVR_VIEWER_TYPE_DAYDREAM: 328 case gvr::ViewerType::GVR_VIEWER_TYPE_DAYDREAM:
412 viewerType = ViewerType::DAYDREAM; 329 viewerType = ViewerType::DAYDREAM;
413 break; 330 break;
414 case gvr::ViewerType::GVR_VIEWER_TYPE_CARDBOARD: 331 case gvr::ViewerType::GVR_VIEWER_TYPE_CARDBOARD:
415 viewerType = ViewerType::CARDBOARD; 332 viewerType = ViewerType::CARDBOARD;
416 break; 333 break;
417 default: 334 default:
418 NOTREACHED(); 335 NOTREACHED();
419 viewerType = ViewerType::UNKNOWN_TYPE; 336 viewerType = ViewerType::UNKNOWN_TYPE;
420 break; 337 break;
421 } 338 }
422 UMA_HISTOGRAM_ENUMERATION("VRViewerType", static_cast<int>(viewerType), 339 UMA_HISTOGRAM_ENUMERATION("VRViewerType", static_cast<int>(viewerType),
423 static_cast<int>(ViewerType::VIEWER_TYPE_MAX)); 340 static_cast<int>(ViewerType::VIEWER_TYPE_MAX));
424 } 341 }
425 342
426 void VrShellGl::InitializeRenderer() { 343 void VrShellGl::InitializeRenderer() {
344 // While WebVR is going through the compositor path, it shares
345 // the same texture ID. This will change once it gets its own
346 // surface, but store it separately to avoid future confusion.
347 // TODO(klausw,crbug.com/655722): remove this.
348 webvr_texture_id_ = content_texture_id_;
349
427 gvr_api_->InitializeGl(); 350 gvr_api_->InitializeGl();
428 webvr_head_pose_.assign(kPoseRingBufferSize, 351 webvr_head_pose_.assign(kPoseRingBufferSize,
429 gvr_api_->GetHeadSpaceFromStartSpaceRotation( 352 gvr_api_->GetHeadSpaceFromStartSpaceRotation(
430 gvr::GvrApi::GetTimePointNow())); 353 gvr::GvrApi::GetTimePointNow()));
431 354
432 std::vector<gvr::BufferSpec> specs; 355 std::vector<gvr::BufferSpec> specs;
433 // For kFramePrimaryBuffer (primary VrShell and WebVR content) 356 // For kFramePrimaryBuffer (primary VrShell and WebVR content)
434 specs.push_back(gvr_api_->CreateBufferSpec()); 357 specs.push_back(gvr_api_->CreateBufferSpec());
435 render_size_primary_ = specs[kFramePrimaryBuffer].GetSize(); 358 render_size_primary_ = specs[kFramePrimaryBuffer].GetSize();
436 render_size_vrshell_ = render_size_primary_;
437 359
438 // For kFrameHeadlockedBuffer (for WebVR insecure content warning). 360 // For kFrameHeadlockedBuffer (for WebVR insecure content warning).
439 // Set this up at fixed resolution, the (smaller) FOV gets set below. 361 // Set this up at fixed resolution, the (smaller) FOV gets set below.
440 specs.push_back(gvr_api_->CreateBufferSpec()); 362 specs.push_back(gvr_api_->CreateBufferSpec());
441 specs.back().SetSize(kHeadlockedBufferDimensions); 363 specs.back().SetSize(kHeadlockedBufferDimensions);
442 render_size_headlocked_ = specs[kFrameHeadlockedBuffer].GetSize(); 364 render_size_headlocked_ = specs[kFrameHeadlockedBuffer].GetSize();
443 365
444 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapChain(specs))); 366 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapChain(specs)));
445 367
446 vr_shell_renderer_.reset(new VrShellRenderer()); 368 vr_shell_renderer_.reset(new VrShellRenderer());
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 std::unique_ptr<blink::WebInputEvent> event) { 625 std::unique_ptr<blink::WebInputEvent> event) {
704 DCHECK(input_target != InputTarget::NONE); 626 DCHECK(input_target != InputTarget::NONE);
705 auto&& target = input_target == InputTarget::CONTENT 627 auto&& target = input_target == InputTarget::CONTENT
706 ? &VrShell::ProcessContentGesture 628 ? &VrShell::ProcessContentGesture
707 : &VrShell::ProcessUIGesture; 629 : &VrShell::ProcessUIGesture;
708 main_thread_task_runner_->PostTask( 630 main_thread_task_runner_->PostTask(
709 FROM_HERE, 631 FROM_HERE,
710 base::Bind(target, weak_vr_shell_, base::Passed(std::move(event)))); 632 base::Bind(target, weak_vr_shell_, base::Passed(std::move(event))));
711 } 633 }
712 634
713 void VrShellGl::DrawFrame(int16_t frame_index) { 635 void VrShellGl::DrawFrame() {
714 TRACE_EVENT1("gpu", "VrShellGl::DrawFrame", "frame", frame_index); 636 TRACE_EVENT0("gpu", "VrShellGl::DrawFrame");
715 637
716 // Reset the viewport list to just the pair of viewports for the 638 // Reset the viewport list to just the pair of viewports for the
717 // primary buffer each frame. Head-locked viewports get added by 639 // primary buffer each frame. Head-locked viewports get added by
718 // DrawVrShell if needed. 640 // DrawVrShell if needed.
719 buffer_viewport_list_->SetToRecommendedBufferViewports(); 641 buffer_viewport_list_->SetToRecommendedBufferViewports();
720 642
721 // If needed, resize the primary buffer for use with WebVR.
722 if (web_vr_mode_) {
723 if (render_size_primary_ != webvr_surface_size_) {
724 if (!webvr_surface_size_.width) {
725 return;
726 }
727 render_size_primary_ = webvr_surface_size_;
728 swap_chain_->ResizeBuffer(kFramePrimaryBuffer, render_size_primary_);
729 }
730 } else {
731 if (render_size_primary_ != render_size_vrshell_) {
732 render_size_primary_ = render_size_vrshell_;
733 swap_chain_->ResizeBuffer(kFramePrimaryBuffer, render_size_primary_);
734 }
735 }
736
737 TRACE_EVENT_BEGIN0("gpu", "VrShellGl::AcquireFrame");
738 gvr::Frame frame = swap_chain_->AcquireFrame(); 643 gvr::Frame frame = swap_chain_->AcquireFrame();
739 TRACE_EVENT_END0("gpu", "VrShellGl::AcquireFrame");
740 if (!frame.is_valid()) { 644 if (!frame.is_valid()) {
741 return; 645 return;
742 } 646 }
743 frame.BindBuffer(kFramePrimaryBuffer); 647 frame.BindBuffer(kFramePrimaryBuffer);
744 if (web_vr_mode_) { 648 if (web_vr_mode_) {
745 DrawWebVr(); 649 DrawWebVr();
746 } 650 }
747 651
652 uint16_t frame_index;
748 gvr::Mat4f head_pose; 653 gvr::Mat4f head_pose;
749 654
750 // When using async reprojection, we need to know which pose was used in 655 // When using async reprojection, we need to know which pose was used in
751 // the WebVR app for drawing this frame. Only needed if reprojection is 656 // the WebVR app for drawing this frame. Due to unknown amounts of
752 // in use. 657 // buffering in the compositor and SurfaceTexture, we read the pose number
753 if (web_vr_mode_ && gvr_api_->GetAsyncReprojectionEnabled()) { 658 // from a corner pixel. There's no point in doing this for legacy
659 // distortion rendering since that doesn't need a pose, and reading back
660 // pixels is an expensive operation. TODO(klausw,crbug.com/655722): stop
661 // doing this once we have working no-compositor rendering for WebVR.
662 if (web_vr_mode_ && gvr_api_->GetAsyncReprojectionEnabled() &&
663 GetPixelEncodedFrameIndex(&frame_index)) {
754 static_assert(!((kPoseRingBufferSize - 1) & kPoseRingBufferSize), 664 static_assert(!((kPoseRingBufferSize - 1) & kPoseRingBufferSize),
755 "kPoseRingBufferSize must be a power of 2"); 665 "kPoseRingBufferSize must be a power of 2");
756 head_pose = webvr_head_pose_[frame_index % kPoseRingBufferSize]; 666 head_pose = webvr_head_pose_[frame_index % kPoseRingBufferSize];
757 // Process all pending_bounds_ changes targeted for before this frame, being 667 // Process all pending_bounds_ changes targeted for before this frame, being
758 // careful of wrapping frame indices. 668 // careful of wrapping frame indices.
759 static constexpr unsigned max = 669 static constexpr unsigned max =
760 std::numeric_limits<decltype(frame_index_)>::max(); 670 std::numeric_limits<decltype(frame_index_)>::max();
761 static_assert(max > kPoseRingBufferSize * 2, 671 static_assert(max > kPoseRingBufferSize * 2,
762 "To detect wrapping, kPoseRingBufferSize must be smaller " 672 "To detect wrapping, kPoseRingBufferSize must be smaller "
763 "than half of frame_index_ range."); 673 "than half of frame_index_ range.");
764 while (!pending_bounds_.empty()) { 674 while (!pending_bounds_.empty()) {
765 uint16_t index = pending_bounds_.front().first; 675 uint16_t index = pending_bounds_.front().first;
766 // If index is less than the frame_index it's possible we've wrapped, so 676 // If index is less than the frame_index it's possible we've wrapped, so
767 // we extend the range and 'un-wrap' to account for this. 677 // we extend the range and 'un-wrap' to account for this.
768 if (index < frame_index) 678 if (index < frame_index)
769 index += max; 679 index += max;
770 // If the pending bounds change is for an upcoming frame within our buffer 680 // If the pending bounds change is for an upcoming frame within our buffer
771 // size, wait to apply it. Otherwise, apply it immediately. This 681 // size, wait to apply it. Otherwise, apply it immediately. This
772 // guarantees that even if we miss many frames, the queue can't fill up 682 // guarantees that even if we miss many frames, the queue can't fill up
773 // with stale bounds. 683 // with stale bounds.
774 if (index > frame_index && index <= frame_index + kPoseRingBufferSize) 684 if (index > frame_index && index <= frame_index + kPoseRingBufferSize)
775 break; 685 break;
776 686
777 const WebVrBounds& bounds = pending_bounds_.front().second; 687 const BoundsPair& bounds = pending_bounds_.front().second;
778 webvr_left_viewport_->SetSourceUv(bounds.left_bounds); 688 webvr_left_viewport_->SetSourceUv(bounds.first);
779 webvr_right_viewport_->SetSourceUv(bounds.right_bounds); 689 webvr_right_viewport_->SetSourceUv(bounds.second);
780 CreateOrResizeWebVRSurface(bounds.source_size);
781 pending_bounds_.pop(); 690 pending_bounds_.pop();
782 } 691 }
783 buffer_viewport_list_->SetBufferViewport(GVR_LEFT_EYE, 692 buffer_viewport_list_->SetBufferViewport(GVR_LEFT_EYE,
784 *webvr_left_viewport_); 693 *webvr_left_viewport_);
785 buffer_viewport_list_->SetBufferViewport(GVR_RIGHT_EYE, 694 buffer_viewport_list_->SetBufferViewport(GVR_RIGHT_EYE,
786 *webvr_right_viewport_); 695 *webvr_right_viewport_);
787 } else { 696 } else {
788 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); 697 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow();
789 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; 698 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos;
790 head_pose = gvr_api_->GetHeadSpaceFromStartSpaceRotation(target_time); 699 head_pose = gvr_api_->GetHeadSpaceFromStartSpaceRotation(target_time);
791 } 700 }
792 701
793 gvr::Vec3f position = GetTranslation(head_pose); 702 gvr::Vec3f position = GetTranslation(head_pose);
794 if (position.x == 0.0f && position.y == 0.0f && position.z == 0.0f) { 703 if (position.x == 0.0f && position.y == 0.0f && position.z == 0.0f) {
795 // This appears to be a 3DOF pose without a neck model. Add one. 704 // This appears to be a 3DOF pose without a neck model. Add one.
796 // The head pose has redundant data. Assume we're only using the 705 // The head pose has redundant data. Assume we're only using the
797 // object_from_reference_matrix, we're not updating position_external. 706 // object_from_reference_matrix, we're not updating position_external.
798 // TODO: Not sure what object_from_reference_matrix is. The new api removed 707 // TODO: Not sure what object_from_reference_matrix is. The new api removed
799 // it. For now, removing it seems working fine. 708 // it. For now, removing it seems working fine.
800 gvr_api_->ApplyNeckModel(head_pose, 1.0f); 709 gvr_api_->ApplyNeckModel(head_pose, 1.0f);
801 } 710 }
802 711
803 // Update the render position of all UI elements (including desktop). 712 // Update the render position of all UI elements (including desktop).
804 scene_->UpdateTransforms(TimeInMicroseconds()); 713 scene_->UpdateTransforms(TimeInMicroseconds());
805 714
806 { 715 UpdateController(GetForwardVector(head_pose));
807 TRACE_EVENT0("gpu", "VrShellGl::UpdateController");
808 UpdateController(GetForwardVector(head_pose));
809 }
810 716
811 // Finish drawing in the primary buffer, and draw the headlocked buffer 717 DrawVrShell(head_pose, frame);
812 // if needed. This must be the last drawing call, this method will
813 // return with no frame being bound.
814 DrawVrShellAndUnbind(head_pose, frame);
815 718
816 { 719 frame.Unbind();
817 TRACE_EVENT0("gpu", "VrShellGl::Submit"); 720 frame.Submit(*buffer_viewport_list_, head_pose);
818 frame.Submit(*buffer_viewport_list_, head_pose);
819 }
820 721
821 // No need to swap buffers for surfaceless rendering. 722 // No need to swap buffers for surfaceless rendering.
822 if (!surfaceless_rendering_) { 723 if (!surfaceless_rendering_) {
823 // TODO(mthiesse): Support asynchronous SwapBuffers. 724 // TODO(mthiesse): Support asynchronous SwapBuffers.
824 TRACE_EVENT0("gpu", "VrShellGl::SwapBuffers");
825 surface_->SwapBuffers(); 725 surface_->SwapBuffers();
826 } 726 }
827 } 727 }
828 728
829 void VrShellGl::DrawVrShellAndUnbind(const gvr::Mat4f& head_pose, 729 void VrShellGl::DrawVrShell(const gvr::Mat4f& head_pose, gvr::Frame& frame) {
830 gvr::Frame& frame) {
831 TRACE_EVENT0("gpu", "VrShellGl::DrawVrShell"); 730 TRACE_EVENT0("gpu", "VrShellGl::DrawVrShell");
832 std::vector<const ContentRectangle*> head_locked_elements; 731 std::vector<const ContentRectangle*> head_locked_elements;
833 std::vector<const ContentRectangle*> world_elements; 732 std::vector<const ContentRectangle*> world_elements;
834 for (const auto& rect : scene_->GetUiElements()) { 733 for (const auto& rect : scene_->GetUiElements()) {
835 if (!rect->IsVisible()) 734 if (!rect->IsVisible())
836 continue; 735 continue;
837 if (rect->lock_to_fov) { 736 if (rect->lock_to_fov) {
838 head_locked_elements.push_back(rect.get()); 737 head_locked_elements.push_back(rect.get());
839 } else { 738 } else {
840 world_elements.push_back(rect.get()); 739 world_elements.push_back(rect.get());
(...skipping 16 matching lines...) Expand all
857 756
858 const Colorf& backgroundColor = scene_->GetBackgroundColor(); 757 const Colorf& backgroundColor = scene_->GetBackgroundColor();
859 glClearColor(backgroundColor.r, backgroundColor.g, backgroundColor.b, 758 glClearColor(backgroundColor.r, backgroundColor.g, backgroundColor.b,
860 backgroundColor.a); 759 backgroundColor.a);
861 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 760 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
862 } 761 }
863 if (!world_elements.empty()) { 762 if (!world_elements.empty()) {
864 DrawUiView(&head_pose, world_elements, render_size_primary_, 763 DrawUiView(&head_pose, world_elements, render_size_primary_,
865 kViewportListPrimaryOffset); 764 kViewportListPrimaryOffset);
866 } 765 }
867 frame.Unbind(); // Done with the primary buffer.
868 766
869 if (!head_locked_elements.empty()) { 767 if (!head_locked_elements.empty()) {
870 // Add head-locked viewports. The list gets reset to just 768 // Add head-locked viewports. The list gets reset to just
871 // the recommended viewports (for the primary buffer) each frame. 769 // the recommended viewports (for the primary buffer) each frame.
872 buffer_viewport_list_->SetBufferViewport( 770 buffer_viewport_list_->SetBufferViewport(
873 kViewportListHeadlockedOffset + GVR_LEFT_EYE, 771 kViewportListHeadlockedOffset + GVR_LEFT_EYE,
874 *headlocked_left_viewport_); 772 *headlocked_left_viewport_);
875 buffer_viewport_list_->SetBufferViewport( 773 buffer_viewport_list_->SetBufferViewport(
876 kViewportListHeadlockedOffset + GVR_RIGHT_EYE, 774 kViewportListHeadlockedOffset + GVR_RIGHT_EYE,
877 *headlocked_right_viewport_); 775 *headlocked_right_viewport_);
878 776
879 // Bind the headlocked framebuffer. 777 // Bind the headlocked framebuffer.
778 // TODO(mthiesse): We don't unbind this? Maybe some cleanup is in order
779 // here.
880 frame.BindBuffer(kFrameHeadlockedBuffer); 780 frame.BindBuffer(kFrameHeadlockedBuffer);
881 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 781 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
882 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 782 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
883 DrawUiView(nullptr, head_locked_elements, render_size_headlocked_, 783 DrawUiView(nullptr, head_locked_elements, render_size_headlocked_,
884 kViewportListHeadlockedOffset); 784 kViewportListHeadlockedOffset);
885 frame.Unbind(); // Done with the headlocked buffer.
886 } 785 }
887 } 786 }
888 787
788 gvr::Sizei VrShellGl::GetWebVRCompositorSurfaceSize() {
789 // This is a stopgap while we're using the WebVR compositor rendering path.
790 // TODO(klausw,crbug.com/655722): Remove this method and member once we're
791 // using a separate WebVR render surface.
792 return content_tex_physical_size_;
793 }
794
889 void VrShellGl::DrawUiView(const gvr::Mat4f* head_pose, 795 void VrShellGl::DrawUiView(const gvr::Mat4f* head_pose,
890 const std::vector<const ContentRectangle*>& elements, 796 const std::vector<const ContentRectangle*>& elements,
891 const gvr::Sizei& render_size, 797 const gvr::Sizei& render_size,
892 int viewport_offset) { 798 int viewport_offset) {
893 TRACE_EVENT0("gpu", "VrShellGl::DrawUiView"); 799 TRACE_EVENT0("gpu", "VrShellGl::DrawUiView");
894 800
895 gvr::Mat4f view_matrix; 801 gvr::Mat4f view_matrix;
896 if (head_pose) { 802 if (head_pose) {
897 view_matrix = *head_pose; 803 view_matrix = *head_pose;
898 } else { 804 } else {
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
1084 void VrShellGl::DrawWebVr() { 990 void VrShellGl::DrawWebVr() {
1085 TRACE_EVENT0("gpu", "VrShellGl::DrawWebVr"); 991 TRACE_EVENT0("gpu", "VrShellGl::DrawWebVr");
1086 // Don't need face culling, depth testing, blending, etc. Turn it all off. 992 // Don't need face culling, depth testing, blending, etc. Turn it all off.
1087 glDisable(GL_CULL_FACE); 993 glDisable(GL_CULL_FACE);
1088 glDepthMask(GL_FALSE); 994 glDepthMask(GL_FALSE);
1089 glDisable(GL_DEPTH_TEST); 995 glDisable(GL_DEPTH_TEST);
1090 glDisable(GL_SCISSOR_TEST); 996 glDisable(GL_SCISSOR_TEST);
1091 glDisable(GL_BLEND); 997 glDisable(GL_BLEND);
1092 glDisable(GL_POLYGON_OFFSET_FILL); 998 glDisable(GL_POLYGON_OFFSET_FILL);
1093 999
1094 glViewport(0, 0, webvr_surface_size_.width, webvr_surface_size_.height); 1000 glViewport(0, 0, render_size_primary_.width, render_size_primary_.height);
1095 vr_shell_renderer_->GetWebVrRenderer()->Draw(webvr_texture_id_); 1001 vr_shell_renderer_->GetWebVrRenderer()->Draw(webvr_texture_id_);
1096 } 1002 }
1097 1003
1098 void VrShellGl::OnTriggerEvent() { 1004 void VrShellGl::OnTriggerEvent() {
1099 // Set a flag to handle this on the render thread at the next frame. 1005 // Set a flag to handle this on the render thread at the next frame.
1100 touch_pending_ = true; 1006 touch_pending_ = true;
1101 } 1007 }
1102 1008
1103 void VrShellGl::OnPause() { 1009 void VrShellGl::OnPause() {
1104 vsync_task_.Cancel(); 1010 vsync_task_.Cancel();
(...skipping 10 matching lines...) Expand all
1115 OnVSync(); 1021 OnVSync();
1116 } 1022 }
1117 } 1023 }
1118 1024
1119 void VrShellGl::SetWebVrMode(bool enabled) { 1025 void VrShellGl::SetWebVrMode(bool enabled) {
1120 web_vr_mode_ = enabled; 1026 web_vr_mode_ = enabled;
1121 } 1027 }
1122 1028
1123 void VrShellGl::UpdateWebVRTextureBounds(int16_t frame_index, 1029 void VrShellGl::UpdateWebVRTextureBounds(int16_t frame_index,
1124 const gvr::Rectf& left_bounds, 1030 const gvr::Rectf& left_bounds,
1125 const gvr::Rectf& right_bounds, 1031 const gvr::Rectf& right_bounds) {
1126 const gvr::Sizei& source_size) {
1127 if (frame_index < 0) { 1032 if (frame_index < 0) {
1128 webvr_left_viewport_->SetSourceUv(left_bounds); 1033 webvr_left_viewport_->SetSourceUv(left_bounds);
1129 webvr_right_viewport_->SetSourceUv(right_bounds); 1034 webvr_right_viewport_->SetSourceUv(right_bounds);
1130 } else { 1035 } else {
1131 pending_bounds_.emplace( 1036 pending_bounds_.emplace(
1132 frame_index, WebVrBounds(left_bounds, right_bounds, source_size)); 1037 std::make_pair(frame_index, std::make_pair(left_bounds, right_bounds)));
1133 } 1038 }
1134 } 1039 }
1135 1040
1136 void VrShellGl::ContentBoundsChanged(int width, int height) { 1041 void VrShellGl::ContentBoundsChanged(int width, int height) {
1137 TRACE_EVENT0("gpu", "VrShellGl::ContentBoundsChanged"); 1042 TRACE_EVENT0("gpu", "VrShellGl::ContentBoundsChanged");
1138 content_tex_css_width_ = width; 1043 content_tex_css_width_ = width;
1139 content_tex_css_height_ = height; 1044 content_tex_css_height_ = height;
1140 } 1045 }
1141 1046
1142 void VrShellGl::ContentPhysicalBoundsChanged(int width, int height) { 1047 void VrShellGl::ContentPhysicalBoundsChanged(int width, int height) {
(...skipping 13 matching lines...) Expand all
1156 ui_surface_texture_->SetDefaultBufferSize(width, height); 1061 ui_surface_texture_->SetDefaultBufferSize(width, height);
1157 ui_tex_physical_size_.width = width; 1062 ui_tex_physical_size_.width = width;
1158 ui_tex_physical_size_.height = height; 1063 ui_tex_physical_size_.height = height;
1159 } 1064 }
1160 1065
1161 base::WeakPtr<VrShellGl> VrShellGl::GetWeakPtr() { 1066 base::WeakPtr<VrShellGl> VrShellGl::GetWeakPtr() {
1162 return weak_ptr_factory_.GetWeakPtr(); 1067 return weak_ptr_factory_.GetWeakPtr();
1163 } 1068 }
1164 1069
1165 void VrShellGl::OnVSync() { 1070 void VrShellGl::OnVSync() {
1166 while (premature_received_frames_ > 0) {
1167 TRACE_EVENT0("gpu", "VrShellGl::OnWebVRFrameAvailableRetry");
1168 --premature_received_frames_;
1169 OnWebVRFrameAvailable();
1170 }
1171
1172 base::TimeTicks now = base::TimeTicks::Now(); 1071 base::TimeTicks now = base::TimeTicks::Now();
1173 base::TimeTicks target; 1072 base::TimeTicks target;
1174 1073
1175 // Don't send VSyncs until we have a timebase/interval. 1074 // Don't send VSyncs until we have a timebase/interval.
1176 if (vsync_interval_.is_zero()) 1075 if (vsync_interval_.is_zero())
1177 return; 1076 return;
1178 target = now + vsync_interval_; 1077 target = now + vsync_interval_;
1179 int64_t intervals = (target - vsync_timebase_) / vsync_interval_; 1078 int64_t intervals = (target - vsync_timebase_) / vsync_interval_;
1180 target = vsync_timebase_ + intervals * vsync_interval_; 1079 target = vsync_timebase_ + intervals * vsync_interval_;
1181 task_runner_->PostDelayedTask(FROM_HERE, vsync_task_.callback(), 1080 task_runner_->PostDelayedTask(FROM_HERE, vsync_task_.callback(),
1182 target - now); 1081 target - now);
1183 1082
1184 base::TimeDelta time = intervals * vsync_interval_; 1083 base::TimeDelta time = intervals * vsync_interval_;
1185 if (!callback_.is_null()) { 1084 if (!callback_.is_null()) {
1186 SendVSync(time, base::ResetAndReturn(&callback_)); 1085 SendVSync(time, base::ResetAndReturn(&callback_));
1187 } else { 1086 } else {
1188 pending_vsync_ = true; 1087 pending_vsync_ = true;
1189 pending_time_ = time; 1088 pending_time_ = time;
1190 } 1089 }
1191 if (!web_vr_mode_) { 1090 DrawFrame();
1192 DrawFrame(-1);
1193 }
1194 } 1091 }
1195 1092
1196 void VrShellGl::OnRequest(device::mojom::VRVSyncProviderRequest request) { 1093 void VrShellGl::OnRequest(device::mojom::VRVSyncProviderRequest request) {
1197 binding_.Close(); 1094 binding_.Close();
1198 binding_.Bind(std::move(request)); 1095 binding_.Bind(std::move(request));
1199 } 1096 }
1200 1097
1201 void VrShellGl::GetVSync(const GetVSyncCallback& callback) { 1098 void VrShellGl::GetVSync(const GetVSyncCallback& callback) {
1202 if (!pending_vsync_) { 1099 if (!pending_vsync_) {
1203 if (!callback_.is_null()) { 1100 if (!callback_.is_null()) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 void VrShellGl::ResetPose() { 1150 void VrShellGl::ResetPose() {
1254 // Should never call RecenterTracking when using with Daydream viewers. On 1151 // Should never call RecenterTracking when using with Daydream viewers. On
1255 // those devices recentering should only be done via the controller. 1152 // those devices recentering should only be done via the controller.
1256 if (gvr_api_ && gvr_api_->GetViewerType() == GVR_VIEWER_TYPE_CARDBOARD) 1153 if (gvr_api_ && gvr_api_->GetViewerType() == GVR_VIEWER_TYPE_CARDBOARD)
1257 gvr_api_->RecenterTracking(); 1154 gvr_api_->RecenterTracking();
1258 } 1155 }
1259 1156
1260 void VrShellGl::CreateVRDisplayInfo( 1157 void VrShellGl::CreateVRDisplayInfo(
1261 const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback, 1158 const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback,
1262 uint32_t device_id) { 1159 uint32_t device_id) {
1263 // This assumes that the initial webvr_surface_size_ was set to the
1264 // appropriate recommended render resolution as the default size during
1265 // InitializeGl. Revisit if the initialization order changes.
1266 device::mojom::VRDisplayInfoPtr info = VrShell::CreateVRDisplayInfo( 1160 device::mojom::VRDisplayInfoPtr info = VrShell::CreateVRDisplayInfo(
1267 gvr_api_.get(), webvr_surface_size_, device_id); 1161 gvr_api_.get(), content_tex_physical_size_, device_id);
1268 main_thread_task_runner_->PostTask( 1162 main_thread_task_runner_->PostTask(
1269 FROM_HERE, 1163 FROM_HERE,
1270 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info))); 1164 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info)));
1271 } 1165 }
1272 1166
1273 } // namespace vr_shell 1167 } // namespace vr_shell
OLDNEW
« no previous file with comments | « chrome/browser/android/vr_shell/vr_shell_gl.h ('k') | chrome/browser/android/vr_shell/vr_shell_renderer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698