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

Side by Side Diff: third_party/WebKit/Source/modules/vr/VRDisplay.cpp

Issue 2729523002: Re-land^2 WebVR compositor bypass via BrowserMain context + mailbox (Closed)
Patch Set: Further cleanups 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 "modules/vr/VRDisplay.h" 5 #include "modules/vr/VRDisplay.h"
6 6
7 #include "core/css/StylePropertySet.h" 7 #include "core/css/StylePropertySet.h"
8 #include "core/dom/DOMException.h" 8 #include "core/dom/DOMException.h"
9 #include "core/dom/DocumentUserGestureToken.h" 9 #include "core/dom/DocumentUserGestureToken.h"
10 #include "core/dom/FrameRequestCallback.h" 10 #include "core/dom/FrameRequestCallback.h"
11 #include "core/dom/Fullscreen.h"
12 #include "core/dom/ScriptedAnimationController.h" 11 #include "core/dom/ScriptedAnimationController.h"
13 #include "core/dom/TaskRunnerHelper.h" 12 #include "core/dom/TaskRunnerHelper.h"
13 #include "core/frame/FrameView.h"
14 #include "core/frame/ImageBitmap.h"
14 #include "core/frame/UseCounter.h" 15 #include "core/frame/UseCounter.h"
15 #include "core/inspector/ConsoleMessage.h" 16 #include "core/inspector/ConsoleMessage.h"
16 #include "core/loader/DocumentLoader.h" 17 #include "core/loader/DocumentLoader.h"
17 #include "gpu/command_buffer/client/gles2_interface.h" 18 #include "gpu/command_buffer/client/gles2_interface.h"
18 #include "modules/EventTargetModules.h" 19 #include "modules/EventTargetModules.h"
19 #include "modules/vr/NavigatorVR.h" 20 #include "modules/vr/NavigatorVR.h"
20 #include "modules/vr/VRController.h" 21 #include "modules/vr/VRController.h"
21 #include "modules/vr/VRDisplayCapabilities.h" 22 #include "modules/vr/VRDisplayCapabilities.h"
22 #include "modules/vr/VREyeParameters.h" 23 #include "modules/vr/VREyeParameters.h"
23 #include "modules/vr/VRFrameData.h" 24 #include "modules/vr/VRFrameData.h"
24 #include "modules/vr/VRLayer.h" 25 #include "modules/vr/VRLayer.h"
25 #include "modules/vr/VRPose.h" 26 #include "modules/vr/VRPose.h"
26 #include "modules/vr/VRStageParameters.h" 27 #include "modules/vr/VRStageParameters.h"
27 #include "modules/webgl/WebGLRenderingContextBase.h" 28 #include "modules/webgl/WebGLRenderingContextBase.h"
28 #include "platform/Histogram.h" 29 #include "platform/Histogram.h"
29 #include "platform/UserGestureIndicator.h" 30 #include "platform/UserGestureIndicator.h"
30 #include "public/platform/Platform.h" 31 #include "public/platform/Platform.h"
31 #include "wtf/AutoReset.h" 32 #include "wtf/AutoReset.h"
32 #include "wtf/Time.h" 33 #include "wtf/Time.h"
33 34
34 #include <array> 35 #include <array>
35 36
36 namespace blink { 37 namespace blink {
37 38
38 namespace { 39 namespace {
39 40
40 // Magic numbers used to mark valid pose index values encoded in frame
41 // data. Must match the magic numbers used in vr_shell.cc.
42 static constexpr std::array<uint8_t, 2> kWebVrPosePixelMagicNumbers{{42, 142}};
43
44 VREye stringToVREye(const String& whichEye) { 41 VREye stringToVREye(const String& whichEye) {
45 if (whichEye == "left") 42 if (whichEye == "left")
46 return VREyeLeft; 43 return VREyeLeft;
47 if (whichEye == "right") 44 if (whichEye == "right")
48 return VREyeRight; 45 return VREyeRight;
49 return VREyeNone; 46 return VREyeNone;
50 } 47 }
51 48
52 } // namespace 49 } // namespace
53 50
54 VRDisplay::VRDisplay(NavigatorVR* navigatorVR, 51 VRDisplay::VRDisplay(NavigatorVR* navigatorVR,
55 device::mojom::blink::VRDisplayPtr display, 52 device::mojom::blink::VRDisplayPtr display,
56 device::mojom::blink::VRDisplayClientRequest request) 53 device::mojom::blink::VRDisplayClientRequest request)
57 : ContextLifecycleObserver(navigatorVR->document()), 54 : ContextLifecycleObserver(navigatorVR->document()),
58 m_navigatorVR(navigatorVR), 55 m_navigatorVR(navigatorVR),
59 m_capabilities(new VRDisplayCapabilities()), 56 m_capabilities(new VRDisplayCapabilities()),
60 m_eyeParametersLeft(new VREyeParameters()), 57 m_eyeParametersLeft(new VREyeParameters()),
61 m_eyeParametersRight(new VREyeParameters()), 58 m_eyeParametersRight(new VREyeParameters()),
62 m_fullscreenCheckTimer(
63 TaskRunnerHelper::get(TaskType::UnspecedTimer,
64 navigatorVR->document()->frame()),
65 this,
66 &VRDisplay::onFullscreenCheck),
67 m_display(std::move(display)), 59 m_display(std::move(display)),
60 m_submit_frame_client_binding(this),
68 m_displayClientBinding(this, std::move(request)) {} 61 m_displayClientBinding(this, std::move(request)) {}
69 62
70 VRDisplay::~VRDisplay() {} 63 VRDisplay::~VRDisplay() {}
71 64
72 VRController* VRDisplay::controller() { 65 VRController* VRDisplay::controller() {
73 return m_navigatorVR->controller(); 66 return m_navigatorVR->controller();
74 } 67 }
75 68
76 void VRDisplay::update(const device::mojom::blink::VRDisplayInfoPtr& display) { 69 void VRDisplay::update(const device::mojom::blink::VRDisplayInfoPtr& display) {
77 m_displayId = display->index; 70 m_displayId = display->index;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 return m_eyeParametersRight; 144 return m_eyeParametersRight;
152 default: 145 default:
153 return nullptr; 146 return nullptr;
154 } 147 }
155 } 148 }
156 149
157 int VRDisplay::requestAnimationFrame(FrameRequestCallback* callback) { 150 int VRDisplay::requestAnimationFrame(FrameRequestCallback* callback) {
158 Document* doc = this->document(); 151 Document* doc = this->document();
159 if (!doc) 152 if (!doc)
160 return 0; 153 return 0;
154 VLOG(1) << __FUNCTION__ << ";;;";
161 m_pendingRaf = true; 155 m_pendingRaf = true;
162 if (!m_vrVSyncProvider.is_bound()) { 156 if (!m_vrVSyncProvider.is_bound()) {
163 ConnectVSyncProvider(); 157 ConnectVSyncProvider();
164 } else if (!m_displayBlurred && !m_pendingVsync) { 158 } else if (!m_displayBlurred && !m_pendingVsync) {
165 m_pendingVsync = true; 159 m_pendingVsync = true;
166 m_vrVSyncProvider->GetVSync(convertToBaseCallback( 160 m_vrVSyncProvider->GetVSync(convertToBaseCallback(
167 WTF::bind(&VRDisplay::OnVSync, wrapWeakPersistent(this)))); 161 WTF::bind(&VRDisplay::OnVSync, wrapWeakPersistent(this))));
168 } 162 }
169 callback->m_useLegacyTimeBase = false; 163 callback->m_useLegacyTimeBase = false;
170 return ensureScriptedAnimationController(doc).registerCallback(callback); 164 return ensureScriptedAnimationController(doc).registerCallback(callback);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 // allowed outside a user gesture so that the presented content may be 226 // allowed outside a user gesture so that the presented content may be
233 // updated. 227 // updated.
234 if (firstPresent && !UserGestureIndicator::utilizeUserGesture()) { 228 if (firstPresent && !UserGestureIndicator::utilizeUserGesture()) {
235 DOMException* exception = DOMException::create( 229 DOMException* exception = DOMException::create(
236 InvalidStateError, "API can only be initiated by a user gesture."); 230 InvalidStateError, "API can only be initiated by a user gesture.");
237 resolver->reject(exception); 231 resolver->reject(exception);
238 ReportPresentationResult(PresentationResult::NotInitiatedByUserGesture); 232 ReportPresentationResult(PresentationResult::NotInitiatedByUserGesture);
239 return promise; 233 return promise;
240 } 234 }
241 235
242 // TODO(mthiesse): Remove fullscreen requirement for presentation. See
243 // crbug.com/687369
244 Document* doc = this->document();
245 if (!doc || !Fullscreen::fullscreenEnabled(*doc)) {
246 DOMException* exception =
247 DOMException::create(InvalidStateError, "Fullscreen is not enabled.");
248 resolver->reject(exception);
249 ReportPresentationResult(PresentationResult::FullscreenNotEnabled);
250 return promise;
251 }
252
253 // A valid number of layers must be provided in order to present. 236 // A valid number of layers must be provided in order to present.
254 if (layers.size() == 0 || layers.size() > m_capabilities->maxLayers()) { 237 if (layers.size() == 0 || layers.size() > m_capabilities->maxLayers()) {
255 forceExitPresent(); 238 forceExitPresent();
256 DOMException* exception = 239 DOMException* exception =
257 DOMException::create(InvalidStateError, "Invalid number of layers."); 240 DOMException::create(InvalidStateError, "Invalid number of layers.");
258 resolver->reject(exception); 241 resolver->reject(exception);
259 ReportPresentationResult(PresentationResult::InvalidNumberOfLayers); 242 ReportPresentationResult(PresentationResult::InvalidNumberOfLayers);
260 return promise; 243 return promise;
261 } 244 }
262 245
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 "VR Presentation not implemented for this VRDisplay."); 371 "VR Presentation not implemented for this VRDisplay.");
389 while (!m_pendingPresentResolvers.isEmpty()) { 372 while (!m_pendingPresentResolvers.isEmpty()) {
390 ScriptPromiseResolver* resolver = m_pendingPresentResolvers.takeFirst(); 373 ScriptPromiseResolver* resolver = m_pendingPresentResolvers.takeFirst();
391 resolver->reject(exception); 374 resolver->reject(exception);
392 } 375 }
393 ReportPresentationResult( 376 ReportPresentationResult(
394 PresentationResult::PresentationNotSupportedByDisplay); 377 PresentationResult::PresentationNotSupportedByDisplay);
395 return; 378 return;
396 } else { 379 } else {
397 if (m_layer.source().isHTMLCanvasElement()) { 380 if (m_layer.source().isHTMLCanvasElement()) {
398 HTMLCanvasElement* canvas = m_layer.source().getAsHTMLCanvasElement(); 381 // Stop unneeded compositor updates. We do so by hiding the view. We can't
399 // TODO(klausw,crbug.com/655722): Need a proper VR compositor, but 382 // hide the page, doing so causes an assertion failure (!m_isHidden) in
400 // for the moment on mobile we'll just make the canvas fullscreen 383 // DrawingBuffer::prepareTextureMailboxInternal(). Do this only when we're
401 // so that VrShell can pick it up through the standard (high 384 // actually presenting (m_isPresenting is true), see corresponding show()
402 // latency) compositing path. auto canvas = 385 // in forceExitPresent(). Otherwise the view may remain hidden for failing
403 // m_layer.source().getAsHTMLCanvasElement(); 386 // DON flow.
404 auto inlineStyle = canvas->inlineStyle(); 387 m_navigatorVR->document()->view()->hide();
405 if (inlineStyle) {
406 // THREE.js's VREffect sets explicit style.width/height on its rendering
407 // canvas based on the non-fullscreen window dimensions, and it keeps
408 // those unchanged when presenting. Unfortunately it appears that a
409 // fullscreened canvas just gets centered if it has explicitly set a
410 // size smaller than the fullscreen dimensions. Manually set size to
411 // 100% in this case and restore it when exiting fullscreen. This is a
412 // stopgap measure since THREE.js's usage appears legal according to the
413 // WebVR API spec. This will no longer be necessary once we can get rid
414 // of this fullscreen hack.
415 m_fullscreenOrigWidth = inlineStyle->getPropertyValue(CSSPropertyWidth);
416 if (!m_fullscreenOrigWidth.isNull()) {
417 canvas->setInlineStyleProperty(CSSPropertyWidth, "100%");
418 }
419 m_fullscreenOrigHeight =
420 inlineStyle->getPropertyValue(CSSPropertyHeight);
421 if (!m_fullscreenOrigHeight.isNull()) {
422 canvas->setInlineStyleProperty(CSSPropertyHeight, "100%");
423 }
424 } else {
425 m_fullscreenOrigWidth = String();
426 m_fullscreenOrigHeight = String();
427 }
428
429 if (doc) {
430 // Since the callback for requestPresent is asynchronous, we've lost our
431 // UserGestureToken, and need to create a new one to enter fullscreen.
432 gestureIndicator = WTF::wrapUnique(
433 new UserGestureIndicator(DocumentUserGestureToken::create(
434 doc, UserGestureToken::Status::PossiblyExistingGesture)));
435 }
436 Fullscreen::requestFullscreen(*canvas);
437
438 // Check to see if the canvas is still the current fullscreen
439 // element once every 2 seconds.
440 m_fullscreenCheckTimer.startRepeating(2.0, BLINK_FROM_HERE);
441 m_reenteredFullscreen = false;
442 } else { 388 } else {
443 DCHECK(m_layer.source().isOffscreenCanvas()); 389 DCHECK(m_layer.source().isOffscreenCanvas());
444 // TODO(junov, crbug.com/695497): Implement OffscreenCanvas presentation 390 // TODO(junov, crbug.com/695497): Implement OffscreenCanvas presentation
445 forceExitPresent(); 391 forceExitPresent();
446 DOMException* exception = DOMException::create( 392 DOMException* exception = DOMException::create(
447 InvalidStateError, "OffscreenCanvas presentation not implemented."); 393 InvalidStateError, "OffscreenCanvas presentation not implemented.");
448 while (!m_pendingPresentResolvers.isEmpty()) { 394 while (!m_pendingPresentResolvers.isEmpty()) {
449 ScriptPromiseResolver* resolver = m_pendingPresentResolvers.takeFirst(); 395 ScriptPromiseResolver* resolver = m_pendingPresentResolvers.takeFirst();
450 resolver->reject(exception); 396 resolver->reject(exception);
451 } 397 }
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 return; 502 return;
557 } 503 }
558 504
559 if (!m_contextGL) { 505 if (!m_contextGL) {
560 // Something got confused, we can't submit frames without a GL context. 506 // Something got confused, we can't submit frames without a GL context.
561 return; 507 return;
562 } 508 }
563 509
564 // No frame Id to write before submitting the frame. 510 // No frame Id to write before submitting the frame.
565 if (m_vrFrameId < 0) { 511 if (m_vrFrameId < 0) {
566 m_display->SubmitFrame(m_framePose.Clone()); 512 m_display->SubmitFrame(
513 m_framePose.Clone(),
514 m_submit_frame_client_binding.CreateInterfacePtrAndBind());
567 return; 515 return;
568 } 516 }
569 517
570 // Write the frame number for the pose used into a bottom left pixel block. 518 m_contextGL->Flush();
571 // It is read by chrome/browser/android/vr_shell/vr_shell.cc to associate 519 // m_contextGL->Finish();
572 // the correct corresponding pose for submission. 520 auto elem = m_layer.source();
573 auto gl = m_contextGL; 521 ImageBitmap* image;
522 if (elem.isHTMLCanvasElement()) {
523 image = ImageBitmap::create(elem.getAsHTMLCanvasElement(),
524 WTF::nullopt, ImageBitmapOptions());
525 } else {
526 image = ImageBitmap::create(elem.getAsOffscreenCanvas(),
527 WTF::nullopt, ImageBitmapOptions());
528 }
529 StaticBitmapImage* bitmap = image->bitmapImage();
530 auto img = bitmap->imageForCurrentFrame(ColorBehavior::tag());
531 bitmap->ensureMailbox();
532 bitmap->transfer();
533 VLOG(1) << __FUNCTION__ << ";;; got bitmap, hasMailbox=" <<
534 bitmap->hasMailbox();
535 auto mailbox = bitmap->mailbox();
536 m_contextGL->WaitSyncTokenCHROMIUM(bitmap->syncToken().GetData());
537 VLOG(1) << __FUNCTION__ << ";;; got mailbox, name=" <<
538 (int)mailbox.name[0] << "," << (int)mailbox.name[1] << "," <<
539 (int)mailbox.name[2] << "," << (int)mailbox.name[3] << "," <<
540 (int)mailbox.name[4] << "," << (int)mailbox.name[5] << "," <<
541 (int)mailbox.name[6] << "," << (int)mailbox.name[7] << "," <<
542 (int)mailbox.name[8] << "," << (int)mailbox.name[9] << "," <<
543 (int)mailbox.name[10] << "," << (int)mailbox.name[11] << "," <<
544 (int)mailbox.name[12] << "," << (int)mailbox.name[13] << "," <<
545 (int)mailbox.name[14] << "," << (int)mailbox.name[15];
574 546
575 // We must ensure that the WebGL app's GL state is preserved. We do this by 547 m_framePose->mailbox = gpu::mojom::blink::Mailbox::New();
576 // calling low-level GL commands directly so that the rendering context's 548 WTF::Vector<int8_t> tmpname(GL_MAILBOX_SIZE_CHROMIUM);
577 // saved parameters don't get overwritten. 549 memcpy(&tmpname[0], &mailbox.name[0], GL_MAILBOX_SIZE_CHROMIUM);
550 m_framePose->mailbox->name = std::move(tmpname);
551 //m_prevImage = bitmap;
578 552
579 gl->Enable(GL_SCISSOR_TEST); 553 m_framePose->frameId = m_vrFrameId;
580 // Use a few pixels to ensure we get a clean color. The resolution for the 554 VLOG(1) << __FUNCTION__ << ";;; SubmitFrame WAIT for frame=" << m_vrFrameId;
581 // WebGL buffer may not match the final rendered destination size, and
582 // texture filtering could interfere for single pixels. This isn't visible
583 // since the final rendering hides the edges via a vignette effect.
584 gl->Scissor(0, 0, 4, 4);
585 gl->ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
586 // Careful with the arithmetic here. Float color 1.f is equivalent to int 255.
587 // Use the low byte of the index as the red component, and store an arbitrary
588 // magic number in green/blue. This number must match the reading code in
589 // vr_shell.cc. Avoid all-black/all-white.
590 gl->ClearColor((m_vrFrameId & 255) / 255.0f,
591 kWebVrPosePixelMagicNumbers[0] / 255.0f,
592 kWebVrPosePixelMagicNumbers[1] / 255.0f, 1.0f);
593 gl->Clear(GL_COLOR_BUFFER_BIT);
594 555
595 // Set the GL state back to what was set by the WebVR application. 556 // There's two types of synchronization needed for submitting frames:
596 m_renderingContext->restoreScissorEnabled(); 557 // - Before submitting, need to wait for the previous frame to be
597 m_renderingContext->restoreScissorBox(); 558 // pulled off the transfer surface to avoid lost frames.
598 m_renderingContext->restoreColorMask(); 559 // - After submitting, need to wait for the mailbox to be consumed,
599 m_renderingContext->restoreClearColor(); 560 // and must remain inside the execution context while waiting.
561 while (m_pendingPreviousFrameRender) {
562 if (!m_submit_frame_client_binding.WaitForIncomingMethodCall()) {
563 LOG(ERROR) << __FUNCTION__ << ": failed to receive SubmitFrame response";
564 break;
565 }
566 }
600 567
601 m_display->SubmitFrame(m_framePose.Clone()); 568 VLOG(1) << __FUNCTION__ << ";;; SubmitFrame START for frame=" << m_vrFrameId;
569
570 m_pendingPreviousFrameRender = true;
571 m_pendingSubmitFrame = true;
572
573 m_display->SubmitFrame(
574 m_framePose.Clone(),
575 m_submit_frame_client_binding.CreateInterfacePtrAndBind());
576 while (m_pendingSubmitFrame) {
577 if (!m_submit_frame_client_binding.WaitForIncomingMethodCall()) {
578 LOG(ERROR) << __FUNCTION__ << ": failed to receive SubmitFrame response";
579 break;
580 }
581 }
582
583 #define WAIT_FOR_CURRENT_RENDER_TO_FINISH 0
584 #if WAIT_FOR_CURRENT_RENDER_TO_FINISH
585 VLOG(1) << __FUNCTION__ << ";;; SubmitFrame WAIT RENDER for frame=" << m_vrFra meId;
586 while (m_pendingPreviousFrameRender) {
587 if (!m_submit_frame_client_binding.WaitForIncomingMethodCall()) {
588 LOG(ERROR) << __FUNCTION__ << ": failed to receive SubmitFrame response";
589 break;
590 }
591 }
592 #endif
593
594 VLOG(1) << __FUNCTION__ << ";;; SubmitFrame DONE for frame=" << m_vrFrameId;
595 }
596
597 void VRDisplay::OnSubmitFrameTransferred() {
598 m_pendingSubmitFrame = false;
599 }
600
601 void VRDisplay::OnSubmitFrameRendered() {
602 m_pendingPreviousFrameRender = false;
602 } 603 }
603 604
604 Document* VRDisplay::document() { 605 Document* VRDisplay::document() {
605 return m_navigatorVR->document(); 606 return m_navigatorVR->document();
606 } 607 }
607 608
608 void VRDisplay::OnPresentChange() { 609 void VRDisplay::OnPresentChange() {
609 if (m_isPresenting && !m_isValidDeviceForPresenting) { 610 if (m_isPresenting && !m_isValidDeviceForPresenting) {
610 VLOG(1) << __FUNCTION__ << ": device not valid, not sending event"; 611 VLOG(1) << __FUNCTION__ << ": device not valid, not sending event";
611 return; 612 return;
(...skipping 17 matching lines...) Expand all
629 630
630 void VRDisplay::onDisconnected() { 631 void VRDisplay::onDisconnected() {
631 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create( 632 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create(
632 EventTypeNames::vrdisplaydisconnect, true, false, this, "disconnect")); 633 EventTypeNames::vrdisplaydisconnect, true, false, this, "disconnect"));
633 } 634 }
634 635
635 void VRDisplay::stopPresenting() { 636 void VRDisplay::stopPresenting() {
636 if (m_isPresenting) { 637 if (m_isPresenting) {
637 if (!m_capabilities->hasExternalDisplay()) { 638 if (!m_capabilities->hasExternalDisplay()) {
638 if (m_layer.source().isHTMLCanvasElement()) { 639 if (m_layer.source().isHTMLCanvasElement()) {
639 auto canvas = m_layer.source().getAsHTMLCanvasElement(); 640 m_navigatorVR->document()->view()->show();
640 Fullscreen::fullyExitFullscreen(canvas->document());
641 m_fullscreenCheckTimer.stop();
642 if (!m_fullscreenOrigWidth.isNull()) {
643 canvas->setInlineStyleProperty(CSSPropertyWidth,
644 m_fullscreenOrigWidth);
645 m_fullscreenOrigWidth = String();
646 }
647 if (!m_fullscreenOrigHeight.isNull()) {
648 canvas->setInlineStyleProperty(CSSPropertyWidth,
649 m_fullscreenOrigHeight);
650 m_fullscreenOrigHeight = String();
651 }
652 } else { 641 } else {
653 // TODO(junov, crbug.com/695497): Implement for OffscreenCanvas 642 // TODO(junov, crbug.com/695497): Implement for OffscreenCanvas
654 } 643 }
655 } else { 644 } else {
656 // Can't get into this presentation mode, so nothing to do here. 645 // Can't get into this presentation mode, so nothing to do here.
657 } 646 }
658 m_isPresenting = false; 647 m_isPresenting = false;
659 OnPresentChange(); 648 OnPresentChange();
660 } 649 }
661 650
662 m_renderingContext = nullptr; 651 m_renderingContext = nullptr;
663 m_contextGL = nullptr; 652 m_contextGL = nullptr;
653 m_pendingSubmitFrame = false;
654 m_pendingPreviousFrameRender = false;
664 } 655 }
665 656
666 void VRDisplay::OnActivate(device::mojom::blink::VRDisplayEventReason reason) { 657 void VRDisplay::OnActivate(device::mojom::blink::VRDisplayEventReason reason) {
667 if (!m_navigatorVR->isFocused() || m_displayBlurred) 658 if (!m_navigatorVR->isFocused() || m_displayBlurred)
668 return; 659 return;
669 m_navigatorVR->dispatchVRGestureEvent(VRDisplayEvent::create( 660 m_navigatorVR->dispatchVRGestureEvent(VRDisplayEvent::create(
670 EventTypeNames::vrdisplayactivate, true, false, this, reason)); 661 EventTypeNames::vrdisplayactivate, true, false, this, reason));
671 } 662 }
672 663
673 void VRDisplay::OnDeactivate( 664 void VRDisplay::OnDeactivate(
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 if (!m_navigatorVR->isFocused() || m_vrVSyncProvider.is_bound()) 707 if (!m_navigatorVR->isFocused() || m_vrVSyncProvider.is_bound())
717 return; 708 return;
718 m_display->GetVRVSyncProvider(mojo::MakeRequest(&m_vrVSyncProvider)); 709 m_display->GetVRVSyncProvider(mojo::MakeRequest(&m_vrVSyncProvider));
719 if (m_pendingRaf && !m_displayBlurred) { 710 if (m_pendingRaf && !m_displayBlurred) {
720 m_pendingVsync = true; 711 m_pendingVsync = true;
721 m_vrVSyncProvider->GetVSync(convertToBaseCallback( 712 m_vrVSyncProvider->GetVSync(convertToBaseCallback(
722 WTF::bind(&VRDisplay::OnVSync, wrapWeakPersistent(this)))); 713 WTF::bind(&VRDisplay::OnVSync, wrapWeakPersistent(this))));
723 } 714 }
724 } 715 }
725 716
726 void VRDisplay::onFullscreenCheck(TimerBase*) {
727 DCHECK(m_layer.source().isHTMLCanvasElement());
728 if (!m_isPresenting) {
729 m_fullscreenCheckTimer.stop();
730 return;
731 }
732 // TODO: This is a temporary measure to track if fullscreen mode has been
733 // exited by the UA. If so we need to end VR presentation. Soon we won't
734 // depend on the Fullscreen API to fake VR presentation, so this will
735 // become unnessecary. Until that point, though, this seems preferable to
736 // adding a bunch of notification plumbing to Fullscreen.
737 if (!Fullscreen::isCurrentFullScreenElement(
738 *m_layer.source().getAsHTMLCanvasElement())) {
739 // TODO(mthiesse): Due to asynchronous resizing, we might get kicked out of
740 // fullscreen when changing display parameters upon entering WebVR. So one
741 // time only, we reenter fullscreen after having left it; otherwise we exit
742 // presentation.
743 if (m_reenteredFullscreen) {
744 m_isPresenting = false;
745 OnPresentChange();
746 m_fullscreenCheckTimer.stop();
747 if (m_display)
748 m_display->ExitPresent();
749 return;
750 }
751 m_reenteredFullscreen = true;
752 auto canvas = m_layer.source().getAsHTMLCanvasElement();
753 Document* doc = this->document();
754 std::unique_ptr<UserGestureIndicator> gestureIndicator;
755 if (doc) {
756 gestureIndicator = WTF::wrapUnique(
757 new UserGestureIndicator(DocumentUserGestureToken::create(
758 doc, UserGestureToken::Status::PossiblyExistingGesture)));
759 }
760 Fullscreen::requestFullscreen(*canvas);
761 }
762 }
763
764 ScriptedAnimationController& VRDisplay::ensureScriptedAnimationController( 717 ScriptedAnimationController& VRDisplay::ensureScriptedAnimationController(
765 Document* doc) { 718 Document* doc) {
766 if (!m_scriptedAnimationController) 719 if (!m_scriptedAnimationController)
767 m_scriptedAnimationController = ScriptedAnimationController::create(doc); 720 m_scriptedAnimationController = ScriptedAnimationController::create(doc);
768 721
769 return *m_scriptedAnimationController; 722 return *m_scriptedAnimationController;
770 } 723 }
771 724
772 void VRDisplay::dispose() { 725 void VRDisplay::dispose() {
773 m_displayClientBinding.Close(); 726 m_displayClientBinding.Close();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
807 visitor->trace(m_stageParameters); 760 visitor->trace(m_stageParameters);
808 visitor->trace(m_eyeParametersLeft); 761 visitor->trace(m_eyeParametersLeft);
809 visitor->trace(m_eyeParametersRight); 762 visitor->trace(m_eyeParametersRight);
810 visitor->trace(m_layer); 763 visitor->trace(m_layer);
811 visitor->trace(m_renderingContext); 764 visitor->trace(m_renderingContext);
812 visitor->trace(m_scriptedAnimationController); 765 visitor->trace(m_scriptedAnimationController);
813 visitor->trace(m_pendingPresentResolvers); 766 visitor->trace(m_pendingPresentResolvers);
814 } 767 }
815 768
816 } // namespace blink 769 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698