OLD | NEW |
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 "cc/resources/texture_mailbox.h" |
7 #include "core/css/StylePropertySet.h" | 8 #include "core/css/StylePropertySet.h" |
8 #include "core/dom/DOMException.h" | 9 #include "core/dom/DOMException.h" |
9 #include "core/dom/DocumentUserGestureToken.h" | 10 #include "core/dom/DocumentUserGestureToken.h" |
10 #include "core/dom/FrameRequestCallback.h" | 11 #include "core/dom/FrameRequestCallback.h" |
11 #include "core/dom/Fullscreen.h" | |
12 #include "core/dom/ScriptedAnimationController.h" | 12 #include "core/dom/ScriptedAnimationController.h" |
13 #include "core/dom/TaskRunnerHelper.h" | 13 #include "core/dom/TaskRunnerHelper.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 |
| 37 #include "core/frame/FrameView.h" |
| 38 |
36 namespace blink { | 39 namespace blink { |
37 | 40 |
38 namespace { | 41 namespace { |
39 | 42 |
| 43 #if 0 |
40 // Magic numbers used to mark valid pose index values encoded in frame | 44 // Magic numbers used to mark valid pose index values encoded in frame |
41 // data. Must match the magic numbers used in vr_shell.cc. | 45 // data. Must match the magic numbers used in vr_shell.cc. |
42 static constexpr std::array<uint8_t, 2> kWebVrPosePixelMagicNumbers{{42, 142}}; | 46 static constexpr std::array<uint8_t, 2> kWebVrPosePixelMagicNumbers{{42, 142}}; |
| 47 #endif |
43 | 48 |
44 VREye stringToVREye(const String& whichEye) { | 49 VREye stringToVREye(const String& whichEye) { |
45 if (whichEye == "left") | 50 if (whichEye == "left") |
46 return VREyeLeft; | 51 return VREyeLeft; |
47 if (whichEye == "right") | 52 if (whichEye == "right") |
48 return VREyeRight; | 53 return VREyeRight; |
49 return VREyeNone; | 54 return VREyeNone; |
50 } | 55 } |
51 | 56 |
52 } // namespace | 57 } // namespace |
53 | 58 |
54 VRDisplay::VRDisplay(NavigatorVR* navigatorVR, | 59 VRDisplay::VRDisplay(NavigatorVR* navigatorVR, |
55 device::mojom::blink::VRDisplayPtr display, | 60 device::mojom::blink::VRDisplayPtr display, |
56 device::mojom::blink::VRDisplayClientRequest request) | 61 device::mojom::blink::VRDisplayClientRequest request) |
57 : ContextLifecycleObserver(navigatorVR->document()), | 62 : ContextLifecycleObserver(navigatorVR->document()), |
58 m_navigatorVR(navigatorVR), | 63 m_navigatorVR(navigatorVR), |
59 m_capabilities(new VRDisplayCapabilities()), | 64 m_capabilities(new VRDisplayCapabilities()), |
60 m_eyeParametersLeft(new VREyeParameters()), | 65 m_eyeParametersLeft(new VREyeParameters()), |
61 m_eyeParametersRight(new VREyeParameters()), | 66 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)), | 67 m_display(std::move(display)), |
68 m_displayClientBinding(this, std::move(request)) {} | 68 m_displayClientBinding(this, std::move(request)) {} |
69 | 69 |
70 VRDisplay::~VRDisplay() {} | 70 VRDisplay::~VRDisplay() {} |
71 | 71 |
72 VRController* VRDisplay::controller() { | 72 VRController* VRDisplay::controller() { |
73 return m_navigatorVR->controller(); | 73 return m_navigatorVR->controller(); |
74 } | 74 } |
75 | 75 |
76 void VRDisplay::update(const device::mojom::blink::VRDisplayInfoPtr& display) { | 76 void VRDisplay::update(const device::mojom::blink::VRDisplayInfoPtr& display) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 return m_eyeParametersRight; | 151 return m_eyeParametersRight; |
152 default: | 152 default: |
153 return nullptr; | 153 return nullptr; |
154 } | 154 } |
155 } | 155 } |
156 | 156 |
157 int VRDisplay::requestAnimationFrame(FrameRequestCallback* callback) { | 157 int VRDisplay::requestAnimationFrame(FrameRequestCallback* callback) { |
158 Document* doc = this->document(); | 158 Document* doc = this->document(); |
159 if (!doc) | 159 if (!doc) |
160 return 0; | 160 return 0; |
| 161 VLOG(1) << __FUNCTION__ << ";;;"; |
161 m_pendingRaf = true; | 162 m_pendingRaf = true; |
162 if (!m_vrVSyncProvider.is_bound()) { | 163 if (!m_vrVSyncProvider.is_bound()) { |
163 ConnectVSyncProvider(); | 164 ConnectVSyncProvider(); |
164 } else if (!m_displayBlurred && !m_pendingVsync) { | 165 } else if (!m_displayBlurred && !m_pendingVsync) { |
165 m_pendingVsync = true; | 166 m_pendingVsync = true; |
166 m_vrVSyncProvider->GetVSync(convertToBaseCallback( | 167 m_vrVSyncProvider->GetVSync(convertToBaseCallback( |
167 WTF::bind(&VRDisplay::OnVSync, wrapWeakPersistent(this)))); | 168 WTF::bind(&VRDisplay::OnVSync, wrapWeakPersistent(this)))); |
168 } | 169 } |
169 callback->m_useLegacyTimeBase = false; | 170 callback->m_useLegacyTimeBase = false; |
170 return ensureScriptedAnimationController(doc).registerCallback(callback); | 171 return ensureScriptedAnimationController(doc).registerCallback(callback); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 // allowed outside a user gesture so that the presented content may be | 233 // allowed outside a user gesture so that the presented content may be |
233 // updated. | 234 // updated. |
234 if (firstPresent && !UserGestureIndicator::utilizeUserGesture()) { | 235 if (firstPresent && !UserGestureIndicator::utilizeUserGesture()) { |
235 DOMException* exception = DOMException::create( | 236 DOMException* exception = DOMException::create( |
236 InvalidStateError, "API can only be initiated by a user gesture."); | 237 InvalidStateError, "API can only be initiated by a user gesture."); |
237 resolver->reject(exception); | 238 resolver->reject(exception); |
238 ReportPresentationResult(PresentationResult::NotInitiatedByUserGesture); | 239 ReportPresentationResult(PresentationResult::NotInitiatedByUserGesture); |
239 return promise; | 240 return promise; |
240 } | 241 } |
241 | 242 |
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. | 243 // A valid number of layers must be provided in order to present. |
254 if (layers.size() == 0 || layers.size() > m_capabilities->maxLayers()) { | 244 if (layers.size() == 0 || layers.size() > m_capabilities->maxLayers()) { |
255 forceExitPresent(); | 245 forceExitPresent(); |
256 DOMException* exception = | 246 DOMException* exception = |
257 DOMException::create(InvalidStateError, "Invalid number of layers."); | 247 DOMException::create(InvalidStateError, "Invalid number of layers."); |
258 resolver->reject(exception); | 248 resolver->reject(exception); |
259 ReportPresentationResult(PresentationResult::InvalidNumberOfLayers); | 249 ReportPresentationResult(PresentationResult::InvalidNumberOfLayers); |
260 return promise; | 250 return promise; |
261 } | 251 } |
262 | 252 |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 "VR Presentation not implemented for this VRDisplay."); | 378 "VR Presentation not implemented for this VRDisplay."); |
389 while (!m_pendingPresentResolvers.isEmpty()) { | 379 while (!m_pendingPresentResolvers.isEmpty()) { |
390 ScriptPromiseResolver* resolver = m_pendingPresentResolvers.takeFirst(); | 380 ScriptPromiseResolver* resolver = m_pendingPresentResolvers.takeFirst(); |
391 resolver->reject(exception); | 381 resolver->reject(exception); |
392 } | 382 } |
393 ReportPresentationResult( | 383 ReportPresentationResult( |
394 PresentationResult::PresentationNotSupportedByDisplay); | 384 PresentationResult::PresentationNotSupportedByDisplay); |
395 return; | 385 return; |
396 } else { | 386 } else { |
397 if (m_layer.source().isHTMLCanvasElement()) { | 387 if (m_layer.source().isHTMLCanvasElement()) { |
398 HTMLCanvasElement* canvas = m_layer.source().getAsHTMLCanvasElement(); | 388 // 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 | 389 // 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 | 390 // DrawingBuffer::prepareTextureMailboxInternal(). Do this only when we're |
401 // so that VrShell can pick it up through the standard (high | 391 // actually presenting (m_isPresenting is true), see corresponding show() |
402 // latency) compositing path. auto canvas = | 392 // in forceExitPresent(). Otherwise the view may remain hidden for failing |
403 // m_layer.source().getAsHTMLCanvasElement(); | 393 // DON flow. |
404 auto inlineStyle = canvas->inlineStyle(); | 394 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 { | 395 } else { |
443 DCHECK(m_layer.source().isOffscreenCanvas()); | 396 DCHECK(m_layer.source().isOffscreenCanvas()); |
444 // TODO(junov, crbug.com/695497): Implement OffscreenCanvas presentation | 397 // TODO(junov, crbug.com/695497): Implement OffscreenCanvas presentation |
445 forceExitPresent(); | 398 forceExitPresent(); |
446 DOMException* exception = DOMException::create( | 399 DOMException* exception = DOMException::create( |
447 InvalidStateError, "OffscreenCanvas presentation not implemented."); | 400 InvalidStateError, "OffscreenCanvas presentation not implemented."); |
448 while (!m_pendingPresentResolvers.isEmpty()) { | 401 while (!m_pendingPresentResolvers.isEmpty()) { |
449 ScriptPromiseResolver* resolver = m_pendingPresentResolvers.takeFirst(); | 402 ScriptPromiseResolver* resolver = m_pendingPresentResolvers.takeFirst(); |
450 resolver->reject(exception); | 403 resolver->reject(exception); |
451 } | 404 } |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 // Something got confused, we can't submit frames without a GL context. | 513 // Something got confused, we can't submit frames without a GL context. |
561 return; | 514 return; |
562 } | 515 } |
563 | 516 |
564 // No frame Id to write before submitting the frame. | 517 // No frame Id to write before submitting the frame. |
565 if (m_vrFrameId < 0) { | 518 if (m_vrFrameId < 0) { |
566 m_display->SubmitFrame(m_framePose.Clone()); | 519 m_display->SubmitFrame(m_framePose.Clone()); |
567 return; | 520 return; |
568 } | 521 } |
569 | 522 |
| 523 #if 0 |
570 // Write the frame number for the pose used into a bottom left pixel block. | 524 // Write the frame number for the pose used into a bottom left pixel block. |
571 // It is read by chrome/browser/android/vr_shell/vr_shell.cc to associate | 525 // It is read by chrome/browser/android/vr_shell/vr_shell.cc to associate |
572 // the correct corresponding pose for submission. | 526 // the correct corresponding pose for submission. |
573 auto gl = m_contextGL; | 527 auto gl = m_contextGL; |
574 | 528 |
575 // We must ensure that the WebGL app's GL state is preserved. We do this by | 529 // We must ensure that the WebGL app's GL state is preserved. We do this by |
576 // calling low-level GL commands directly so that the rendering context's | 530 // calling low-level GL commands directly so that the rendering context's |
577 // saved parameters don't get overwritten. | 531 // saved parameters don't get overwritten. |
578 | 532 |
579 gl->Enable(GL_SCISSOR_TEST); | 533 gl->Enable(GL_SCISSOR_TEST); |
(...skipping 10 matching lines...) Expand all Loading... |
590 gl->ClearColor((m_vrFrameId & 255) / 255.0f, | 544 gl->ClearColor((m_vrFrameId & 255) / 255.0f, |
591 kWebVrPosePixelMagicNumbers[0] / 255.0f, | 545 kWebVrPosePixelMagicNumbers[0] / 255.0f, |
592 kWebVrPosePixelMagicNumbers[1] / 255.0f, 1.0f); | 546 kWebVrPosePixelMagicNumbers[1] / 255.0f, 1.0f); |
593 gl->Clear(GL_COLOR_BUFFER_BIT); | 547 gl->Clear(GL_COLOR_BUFFER_BIT); |
594 | 548 |
595 // Set the GL state back to what was set by the WebVR application. | 549 // Set the GL state back to what was set by the WebVR application. |
596 m_renderingContext->restoreScissorEnabled(); | 550 m_renderingContext->restoreScissorEnabled(); |
597 m_renderingContext->restoreScissorBox(); | 551 m_renderingContext->restoreScissorBox(); |
598 m_renderingContext->restoreColorMask(); | 552 m_renderingContext->restoreColorMask(); |
599 m_renderingContext->restoreClearColor(); | 553 m_renderingContext->restoreClearColor(); |
| 554 #endif |
600 | 555 |
| 556 //auto image = m_renderingContext->getImage(PreferAcceleration, SnapshotReason
TransferToImageBitmap); |
| 557 auto elem = m_layer.source(); |
| 558 ImageBitmap* image; |
| 559 if (elem.isHTMLCanvasElement()) { |
| 560 image = ImageBitmap::create(elem.getAsHTMLCanvasElement(), |
| 561 WTF::nullopt, ImageBitmapOptions()); |
| 562 } else { |
| 563 image = ImageBitmap::create(elem.getAsOffscreenCanvas(), |
| 564 WTF::nullopt, ImageBitmapOptions()); |
| 565 } |
| 566 StaticBitmapImage* bitmap = image->bitmapImage(); |
| 567 bitmap->ensureMailbox(); |
| 568 VLOG(1) << __FUNCTION__ << ";;; got bitmap, hasMailbox=" << bitmap->hasMailbox
(); |
| 569 auto mailbox = bitmap->mailbox(); |
| 570 m_contextGL->WaitSyncTokenCHROMIUM(bitmap->syncToken().GetData()); |
| 571 VLOG(1) << __FUNCTION__ << ";;; got mailbox, name=" << (int)mailbox.name[0] <<
"," << (int)mailbox.name[1] << "..."; |
| 572 |
| 573 m_framePose->mailbox = gpu::mojom::blink::Mailbox::New(); |
| 574 WTF::Vector<int8_t> tmpname(GL_MAILBOX_SIZE_CHROMIUM); |
| 575 memcpy(&tmpname[0], &mailbox.name[0], GL_MAILBOX_SIZE_CHROMIUM); |
| 576 m_framePose->mailbox->name = std::move(tmpname); |
| 577 |
| 578 m_framePose->frameId = m_vrFrameId; |
| 579 VLOG(1) << __FUNCTION__ << ";;; SubmitFrame frame=" << m_vrFrameId; |
601 m_display->SubmitFrame(m_framePose.Clone()); | 580 m_display->SubmitFrame(m_framePose.Clone()); |
602 } | 581 } |
603 | 582 |
604 Document* VRDisplay::document() { | 583 Document* VRDisplay::document() { |
605 return m_navigatorVR->document(); | 584 return m_navigatorVR->document(); |
606 } | 585 } |
607 | 586 |
608 void VRDisplay::OnPresentChange() { | 587 void VRDisplay::OnPresentChange() { |
609 if (m_isPresenting && !m_isValidDeviceForPresenting) { | 588 if (m_isPresenting && !m_isValidDeviceForPresenting) { |
610 VLOG(1) << __FUNCTION__ << ": device not valid, not sending event"; | 589 VLOG(1) << __FUNCTION__ << ": device not valid, not sending event"; |
(...skipping 18 matching lines...) Expand all Loading... |
629 | 608 |
630 void VRDisplay::onDisconnected() { | 609 void VRDisplay::onDisconnected() { |
631 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create( | 610 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create( |
632 EventTypeNames::vrdisplaydisconnect, true, false, this, "disconnect")); | 611 EventTypeNames::vrdisplaydisconnect, true, false, this, "disconnect")); |
633 } | 612 } |
634 | 613 |
635 void VRDisplay::stopPresenting() { | 614 void VRDisplay::stopPresenting() { |
636 if (m_isPresenting) { | 615 if (m_isPresenting) { |
637 if (!m_capabilities->hasExternalDisplay()) { | 616 if (!m_capabilities->hasExternalDisplay()) { |
638 if (m_layer.source().isHTMLCanvasElement()) { | 617 if (m_layer.source().isHTMLCanvasElement()) { |
639 auto canvas = m_layer.source().getAsHTMLCanvasElement(); | 618 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 { | 619 } else { |
653 // TODO(junov, crbug.com/695497): Implement for OffscreenCanvas | 620 // TODO(junov, crbug.com/695497): Implement for OffscreenCanvas |
654 } | 621 } |
655 } else { | 622 } else { |
656 // Can't get into this presentation mode, so nothing to do here. | 623 // Can't get into this presentation mode, so nothing to do here. |
657 } | 624 } |
658 m_isPresenting = false; | 625 m_isPresenting = false; |
659 OnPresentChange(); | 626 OnPresentChange(); |
660 } | 627 } |
661 | 628 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
716 if (!m_navigatorVR->isFocused() || m_vrVSyncProvider.is_bound()) | 683 if (!m_navigatorVR->isFocused() || m_vrVSyncProvider.is_bound()) |
717 return; | 684 return; |
718 m_display->GetVRVSyncProvider(mojo::MakeRequest(&m_vrVSyncProvider)); | 685 m_display->GetVRVSyncProvider(mojo::MakeRequest(&m_vrVSyncProvider)); |
719 if (m_pendingRaf && !m_displayBlurred) { | 686 if (m_pendingRaf && !m_displayBlurred) { |
720 m_pendingVsync = true; | 687 m_pendingVsync = true; |
721 m_vrVSyncProvider->GetVSync(convertToBaseCallback( | 688 m_vrVSyncProvider->GetVSync(convertToBaseCallback( |
722 WTF::bind(&VRDisplay::OnVSync, wrapWeakPersistent(this)))); | 689 WTF::bind(&VRDisplay::OnVSync, wrapWeakPersistent(this)))); |
723 } | 690 } |
724 } | 691 } |
725 | 692 |
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( | 693 ScriptedAnimationController& VRDisplay::ensureScriptedAnimationController( |
765 Document* doc) { | 694 Document* doc) { |
766 if (!m_scriptedAnimationController) | 695 if (!m_scriptedAnimationController) |
767 m_scriptedAnimationController = ScriptedAnimationController::create(doc); | 696 m_scriptedAnimationController = ScriptedAnimationController::create(doc); |
768 | 697 |
769 return *m_scriptedAnimationController; | 698 return *m_scriptedAnimationController; |
770 } | 699 } |
771 | 700 |
772 void VRDisplay::dispose() { | 701 void VRDisplay::dispose() { |
773 m_displayClientBinding.Close(); | 702 m_displayClientBinding.Close(); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
807 visitor->trace(m_stageParameters); | 736 visitor->trace(m_stageParameters); |
808 visitor->trace(m_eyeParametersLeft); | 737 visitor->trace(m_eyeParametersLeft); |
809 visitor->trace(m_eyeParametersRight); | 738 visitor->trace(m_eyeParametersRight); |
810 visitor->trace(m_layer); | 739 visitor->trace(m_layer); |
811 visitor->trace(m_renderingContext); | 740 visitor->trace(m_renderingContext); |
812 visitor->trace(m_scriptedAnimationController); | 741 visitor->trace(m_scriptedAnimationController); |
813 visitor->trace(m_pendingPresentResolvers); | 742 visitor->trace(m_pendingPresentResolvers); |
814 } | 743 } |
815 | 744 |
816 } // namespace blink | 745 } // namespace blink |
OLD | NEW |