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

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

Issue 2624633002: Remove Sync GetPose VRService call, implement VRVSyncProvider (Closed)
Patch Set: oops Created 3 years, 10 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"
(...skipping 11 matching lines...) Expand all
22 #include "modules/vr/VREyeParameters.h" 22 #include "modules/vr/VREyeParameters.h"
23 #include "modules/vr/VRFrameData.h" 23 #include "modules/vr/VRFrameData.h"
24 #include "modules/vr/VRLayer.h" 24 #include "modules/vr/VRLayer.h"
25 #include "modules/vr/VRPose.h" 25 #include "modules/vr/VRPose.h"
26 #include "modules/vr/VRStageParameters.h" 26 #include "modules/vr/VRStageParameters.h"
27 #include "modules/webgl/WebGLRenderingContextBase.h" 27 #include "modules/webgl/WebGLRenderingContextBase.h"
28 #include "platform/Histogram.h" 28 #include "platform/Histogram.h"
29 #include "platform/UserGestureIndicator.h" 29 #include "platform/UserGestureIndicator.h"
30 #include "public/platform/Platform.h" 30 #include "public/platform/Platform.h"
31 #include "wtf/AutoReset.h" 31 #include "wtf/AutoReset.h"
32 #include "wtf/Time.h"
32 33
33 #include <array> 34 #include <array>
34 35
35 namespace blink { 36 namespace blink {
36 37
37 namespace { 38 namespace {
38 39
39 // Magic numbers used to mark valid pose index values encoded in frame 40 // Magic numbers used to mark valid pose index values encoded in frame
40 // data. Must match the magic numbers used in vr_shell.cc. 41 // data. Must match the magic numbers used in vr_shell.cc.
41 static constexpr std::array<uint8_t, 2> kWebVrPosePixelMagicNumbers{{42, 142}}; 42 static constexpr std::array<uint8_t, 2> kWebVrPosePixelMagicNumbers{{42, 142}};
42 43
43 VREye stringToVREye(const String& whichEye) { 44 VREye stringToVREye(const String& whichEye) {
44 if (whichEye == "left") 45 if (whichEye == "left")
45 return VREyeLeft; 46 return VREyeLeft;
46 if (whichEye == "right") 47 if (whichEye == "right")
47 return VREyeRight; 48 return VREyeRight;
48 return VREyeNone; 49 return VREyeNone;
49 } 50 }
50 51
51 class VRDisplayFrameRequestCallback : public FrameRequestCallback {
52 public:
53 VRDisplayFrameRequestCallback(VRDisplay* vrDisplay) : m_vrDisplay(vrDisplay) {
54 m_useLegacyTimeBase = true;
55 }
56 ~VRDisplayFrameRequestCallback() override {}
57 void handleEvent(double highResTimeMs) override {
58 Document* doc = m_vrDisplay->document();
59 if (!doc)
60 return;
61
62 // Need to divide by 1000 here because serviceScriptedAnimations expects
63 // time to be given in seconds.
64 m_vrDisplay->serviceScriptedAnimations(
65 doc->loader()->timing().pseudoWallTimeToMonotonicTime(highResTimeMs /
66 1000.0));
67 }
68
69 DEFINE_INLINE_VIRTUAL_TRACE() {
70 visitor->trace(m_vrDisplay);
71
72 FrameRequestCallback::trace(visitor);
73 }
74
75 Member<VRDisplay> m_vrDisplay;
76 };
77
78 } // namespace 52 } // namespace
79 53
80 VRDisplay::VRDisplay(NavigatorVR* navigatorVR, 54 VRDisplay::VRDisplay(NavigatorVR* navigatorVR,
81 device::mojom::blink::VRDisplayPtr display, 55 device::mojom::blink::VRDisplayPtr display,
82 device::mojom::blink::VRDisplayClientRequest request) 56 device::mojom::blink::VRDisplayClientRequest request)
83 : ContextLifecycleObserver(navigatorVR->document()), 57 : ContextLifecycleObserver(navigatorVR->document()),
84 m_navigatorVR(navigatorVR), 58 m_navigatorVR(navigatorVR),
85 m_isConnected(false),
86 m_isPresenting(false),
87 m_isValidDeviceForPresenting(true),
88 m_canUpdateFramePose(true),
89 m_capabilities(new VRDisplayCapabilities()), 59 m_capabilities(new VRDisplayCapabilities()),
90 m_eyeParametersLeft(new VREyeParameters()), 60 m_eyeParametersLeft(new VREyeParameters()),
91 m_eyeParametersRight(new VREyeParameters()), 61 m_eyeParametersRight(new VREyeParameters()),
92 m_depthNear(0.01),
93 m_depthFar(10000.0),
94 m_fullscreenCheckTimer( 62 m_fullscreenCheckTimer(
95 TaskRunnerHelper::get(TaskType::UnspecedTimer, 63 TaskRunnerHelper::get(TaskType::UnspecedTimer,
96 navigatorVR->document()->frame()), 64 navigatorVR->document()->frame()),
97 this, 65 this,
98 &VRDisplay::onFullscreenCheck), 66 &VRDisplay::onFullscreenCheck),
99 m_contextGL(nullptr),
100 m_animationCallbackRequested(false),
101 m_inAnimationFrame(false),
102 m_display(std::move(display)), 67 m_display(std::move(display)),
103 m_binding(this, std::move(request)) {} 68 m_displayClientBinding(this, std::move(request)) {}
104 69
105 VRDisplay::~VRDisplay() {} 70 VRDisplay::~VRDisplay() {}
106 71
107 VRController* VRDisplay::controller() { 72 VRController* VRDisplay::controller() {
108 return m_navigatorVR->controller(); 73 return m_navigatorVR->controller();
109 } 74 }
110 75
111 void VRDisplay::update(const device::mojom::blink::VRDisplayInfoPtr& display) { 76 void VRDisplay::update(const device::mojom::blink::VRDisplayInfoPtr& display) {
112 m_displayId = display->index; 77 m_displayId = display->index;
113 m_displayName = display->displayName; 78 m_displayName = display->displayName;
(...skipping 28 matching lines...) Expand all
142 OnPresentChange(); 107 OnPresentChange();
143 } 108 }
144 } 109 }
145 110
146 void VRDisplay::disconnected() { 111 void VRDisplay::disconnected() {
147 if (m_isConnected) 112 if (m_isConnected)
148 m_isConnected = !m_isConnected; 113 m_isConnected = !m_isConnected;
149 } 114 }
150 115
151 bool VRDisplay::getFrameData(VRFrameData* frameData) { 116 bool VRDisplay::getFrameData(VRFrameData* frameData) {
152 updatePose(); 117 if (!m_framePose || m_displayBlurred)
153
154 if (!m_framePose)
155 return false; 118 return false;
156 119
157 if (!frameData) 120 if (!frameData)
158 return false; 121 return false;
159 122
160 if (m_depthNear == m_depthFar) 123 if (m_depthNear == m_depthFar)
161 return false; 124 return false;
162 125
163 return frameData->update(m_framePose, m_eyeParametersLeft, 126 return frameData->update(m_framePose, m_eyeParametersLeft,
164 m_eyeParametersRight, m_depthNear, m_depthFar); 127 m_eyeParametersRight, m_depthNear, m_depthFar);
165 } 128 }
166 129
167 VRPose* VRDisplay::getPose() { 130 VRPose* VRDisplay::getPose() {
168 updatePose(); 131 if (!m_framePose || m_displayBlurred)
169
170 if (!m_framePose)
171 return nullptr; 132 return nullptr;
172 133
173 VRPose* pose = VRPose::create(); 134 VRPose* pose = VRPose::create();
174 pose->setPose(m_framePose); 135 pose->setPose(m_framePose);
175 return pose; 136 return pose;
176 } 137 }
177 138
178 void VRDisplay::updatePose() {
179 if (m_displayBlurred) {
180 // WebVR spec says to return a null pose when the display is blurred.
181 m_framePose = nullptr;
182 return;
183 }
184 if (m_canUpdateFramePose) {
185 if (!m_display)
186 return;
187 device::mojom::blink::VRPosePtr pose;
188 m_display->GetPose(&pose);
189 m_framePose = std::move(pose);
190 if (m_isPresenting)
191 m_canUpdateFramePose = false;
192 }
193 }
194
195 void VRDisplay::resetPose() { 139 void VRDisplay::resetPose() {
196 if (!m_display) 140 if (!m_display)
197 return; 141 return;
198 142
199 m_display->ResetPose(); 143 m_display->ResetPose();
200 } 144 }
201 145
202 VREyeParameters* VRDisplay::getEyeParameters(const String& whichEye) { 146 VREyeParameters* VRDisplay::getEyeParameters(const String& whichEye) {
203 switch (stringToVREye(whichEye)) { 147 switch (stringToVREye(whichEye)) {
204 case VREyeLeft: 148 case VREyeLeft:
205 return m_eyeParametersLeft; 149 return m_eyeParametersLeft;
206 case VREyeRight: 150 case VREyeRight:
207 return m_eyeParametersRight; 151 return m_eyeParametersRight;
208 default: 152 default:
209 return nullptr; 153 return nullptr;
210 } 154 }
211 } 155 }
212 156
213 int VRDisplay::requestAnimationFrame(FrameRequestCallback* callback) { 157 int VRDisplay::requestAnimationFrame(FrameRequestCallback* callback) {
214 Document* doc = this->document(); 158 Document* doc = this->document();
215 if (!doc) 159 if (!doc)
216 return 0; 160 return 0;
217 161 m_pendingRaf = true;
218 if (!m_animationCallbackRequested) { 162 if (!m_vrVSyncProvider.is_bound()) {
219 doc->requestAnimationFrame(new VRDisplayFrameRequestCallback(this)); 163 ConnectVSyncProvider();
220 m_animationCallbackRequested = true; 164 } else if (!m_displayBlurred) {
165 m_vrVSyncProvider->GetVSync(convertToBaseCallback(
166 WTF::bind(&VRDisplay::OnVSync, wrapWeakPersistent(this))));
221 } 167 }
222
223 callback->m_useLegacyTimeBase = false; 168 callback->m_useLegacyTimeBase = false;
224 return ensureScriptedAnimationController(doc).registerCallback(callback); 169 return ensureScriptedAnimationController(doc).registerCallback(callback);
225 } 170 }
226 171
227 void VRDisplay::cancelAnimationFrame(int id) { 172 void VRDisplay::cancelAnimationFrame(int id) {
228 if (!m_scriptedAnimationController) 173 if (!m_scriptedAnimationController)
229 return; 174 return;
230 m_scriptedAnimationController->cancelCallback(id); 175 m_scriptedAnimationController->cancelCallback(id);
231 } 176 }
232 177
233 void VRDisplay::OnBlur() { 178 void VRDisplay::OnBlur() {
234 m_displayBlurred = true; 179 m_displayBlurred = true;
235 180 m_vrVSyncProvider.reset();
236 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create( 181 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create(
237 EventTypeNames::vrdisplayblur, true, false, this, "")); 182 EventTypeNames::vrdisplayblur, true, false, this, ""));
238 } 183 }
239 184
240 void VRDisplay::OnFocus() { 185 void VRDisplay::OnFocus() {
241 m_displayBlurred = false; 186 m_displayBlurred = false;
242 // Restart our internal doc requestAnimationFrame callback, if it fired while 187 ConnectVSyncProvider();
243 // the display was blurred.
244 // TODO(bajones): Don't use doc->requestAnimationFrame() at all. Animation
245 // frames should be tied to the presenting VR display (e.g. should be serviced
246 // by GVR library callbacks on Android), and not the doc frame rate.
247 if (!m_animationCallbackRequested) {
248 Document* doc = this->document();
249 if (!doc)
250 return;
251 doc->requestAnimationFrame(new VRDisplayFrameRequestCallback(this));
252 }
253 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create( 188 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create(
254 EventTypeNames::vrdisplayfocus, true, false, this, "")); 189 EventTypeNames::vrdisplayfocus, true, false, this, ""));
255 } 190 }
256 191
257 void VRDisplay::serviceScriptedAnimations(double monotonicAnimationStartTime) {
258 if (!m_scriptedAnimationController)
259 return;
260 AutoReset<bool> animating(&m_inAnimationFrame, true);
261 m_animationCallbackRequested = false;
262
263 // We use an internal rAF callback to run the animation loop at the display
264 // speed, and run the user's callback after our internal callback fires.
265 // However, when the display is blurred, we want to pause the animation loop,
266 // so we don't fire the user's callback until the display is focused.
267 if (m_displayBlurred)
268 return;
269 m_scriptedAnimationController->serviceScriptedAnimations(
270 monotonicAnimationStartTime);
271 }
272
273 void ReportPresentationResult(PresentationResult result) { 192 void ReportPresentationResult(PresentationResult result) {
274 // Note that this is called twice for each call to requestPresent - 193 // Note that this is called twice for each call to requestPresent -
275 // one to declare that requestPresent was called, and one for the 194 // one to declare that requestPresent was called, and one for the
276 // result. 195 // result.
277 DEFINE_STATIC_LOCAL( 196 DEFINE_STATIC_LOCAL(
278 EnumerationHistogram, vrPresentationResultHistogram, 197 EnumerationHistogram, vrPresentationResultHistogram,
279 ("VRDisplayPresentResult", 198 ("VRDisplayPresentResult",
280 static_cast<int>(PresentationResult::PresentationResultMax))); 199 static_cast<int>(PresentationResult::PresentationResultMax)));
281 vrPresentationResultHistogram.count(static_cast<int>(result)); 200 vrPresentationResultHistogram.count(static_cast<int>(result));
282 } 201 }
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 kWebVrPosePixelMagicNumbers[1] / 255.0f, 1.0f); 567 kWebVrPosePixelMagicNumbers[1] / 255.0f, 1.0f);
649 gl->Clear(GL_COLOR_BUFFER_BIT); 568 gl->Clear(GL_COLOR_BUFFER_BIT);
650 569
651 // Set the GL state back to what was set by the WebVR application. 570 // Set the GL state back to what was set by the WebVR application.
652 m_renderingContext->restoreScissorEnabled(); 571 m_renderingContext->restoreScissorEnabled();
653 m_renderingContext->restoreScissorBox(); 572 m_renderingContext->restoreScissorBox();
654 m_renderingContext->restoreColorMask(); 573 m_renderingContext->restoreColorMask();
655 m_renderingContext->restoreClearColor(); 574 m_renderingContext->restoreClearColor();
656 575
657 m_display->SubmitFrame(m_framePose.Clone()); 576 m_display->SubmitFrame(m_framePose.Clone());
658 m_canUpdateFramePose = true;
659 } 577 }
660 578
661 Document* VRDisplay::document() { 579 Document* VRDisplay::document() {
662 return m_navigatorVR->document(); 580 return m_navigatorVR->document();
663 } 581 }
664 582
665 void VRDisplay::OnPresentChange() { 583 void VRDisplay::OnPresentChange() {
666 if (m_isPresenting && !m_isValidDeviceForPresenting) { 584 if (m_isPresenting && !m_isValidDeviceForPresenting) {
667 VLOG(1) << __FUNCTION__ << ": device not valid, not sending event"; 585 VLOG(1) << __FUNCTION__ << ": device not valid, not sending event";
668 return; 586 return;
(...skipping 24 matching lines...) Expand all
693 m_navigatorVR->dispatchVRGestureEvent(VRDisplayEvent::create( 611 m_navigatorVR->dispatchVRGestureEvent(VRDisplayEvent::create(
694 EventTypeNames::vrdisplayactivate, true, false, this, reason)); 612 EventTypeNames::vrdisplayactivate, true, false, this, reason));
695 } 613 }
696 614
697 void VRDisplay::OnDeactivate( 615 void VRDisplay::OnDeactivate(
698 device::mojom::blink::VRDisplayEventReason reason) { 616 device::mojom::blink::VRDisplayEventReason reason) {
699 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create( 617 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create(
700 EventTypeNames::vrdisplaydeactivate, true, false, this, reason)); 618 EventTypeNames::vrdisplaydeactivate, true, false, this, reason));
701 } 619 }
702 620
621 void VRDisplay::OnVSync(device::mojom::blink::VRPosePtr pose,
622 mojo::common::mojom::blink::TimeDeltaPtr time) {
623 WTF::TimeDelta timeDelta =
624 WTF::TimeDelta::FromMicroseconds(time->microseconds);
625 // The VSync provider cannot shut down before replying to pending callbacks,
626 // so it will send a null pose with no timestamp to be ignored.
627 if (pose.is_null() && timeDelta.is_zero()) {
628 // We need to keep the VSync loop going because we haven't responded to the
629 // previous rAF yet.
630 m_vrVSyncProvider->GetVSync(convertToBaseCallback(
631 WTF::bind(&VRDisplay::OnVSync, wrapWeakPersistent(this))));
632 return;
633 }
634 if (m_displayBlurred)
635 return;
636 if (!m_scriptedAnimationController)
637 return;
638 Document* doc = this->document();
639 if (!doc)
640 return;
641
642 // Ensure a consistent timebase with document rAF.
643 if (m_timebase < 0) {
644 m_timebase = WTF::monotonicallyIncreasingTime() - timeDelta.InSecondsF();
645 }
646
647 AutoReset<bool> animating(&m_inAnimationFrame, true);
648 m_framePose = std::move(pose);
649 m_pendingRaf = false;
650 m_scriptedAnimationController->serviceScriptedAnimations(
651 m_timebase + timeDelta.InSecondsF());
652 }
653
654 void VRDisplay::ConnectVSyncProvider() {
655 m_display->GetVRVSyncProvider(mojo::MakeRequest(&m_vrVSyncProvider));
656 if (m_pendingRaf && !m_displayBlurred) {
657 m_vrVSyncProvider->GetVSync(convertToBaseCallback(
658 WTF::bind(&VRDisplay::OnVSync, wrapWeakPersistent(this))));
659 }
660 }
661
703 void VRDisplay::onFullscreenCheck(TimerBase*) { 662 void VRDisplay::onFullscreenCheck(TimerBase*) {
704 if (!m_isPresenting) { 663 if (!m_isPresenting) {
705 m_fullscreenCheckTimer.stop(); 664 m_fullscreenCheckTimer.stop();
706 return; 665 return;
707 } 666 }
708 // TODO: This is a temporary measure to track if fullscreen mode has been 667 // TODO: This is a temporary measure to track if fullscreen mode has been
709 // exited by the UA. If so we need to end VR presentation. Soon we won't 668 // exited by the UA. If so we need to end VR presentation. Soon we won't
710 // depend on the Fullscreen API to fake VR presentation, so this will 669 // depend on the Fullscreen API to fake VR presentation, so this will
711 // become unnessecary. Until that point, though, this seems preferable to 670 // become unnessecary. Until that point, though, this seems preferable to
712 // adding a bunch of notification plumbing to Fullscreen. 671 // adding a bunch of notification plumbing to Fullscreen.
(...skipping 25 matching lines...) Expand all
738 697
739 ScriptedAnimationController& VRDisplay::ensureScriptedAnimationController( 698 ScriptedAnimationController& VRDisplay::ensureScriptedAnimationController(
740 Document* doc) { 699 Document* doc) {
741 if (!m_scriptedAnimationController) 700 if (!m_scriptedAnimationController)
742 m_scriptedAnimationController = ScriptedAnimationController::create(doc); 701 m_scriptedAnimationController = ScriptedAnimationController::create(doc);
743 702
744 return *m_scriptedAnimationController; 703 return *m_scriptedAnimationController;
745 } 704 }
746 705
747 void VRDisplay::dispose() { 706 void VRDisplay::dispose() {
748 m_binding.Close(); 707 m_displayClientBinding.Close();
708 m_vrVSyncProvider.reset();
749 } 709 }
750 710
751 ExecutionContext* VRDisplay::getExecutionContext() const { 711 ExecutionContext* VRDisplay::getExecutionContext() const {
752 return ContextLifecycleObserver::getExecutionContext(); 712 return ContextLifecycleObserver::getExecutionContext();
753 } 713 }
754 714
755 const AtomicString& VRDisplay::interfaceName() const { 715 const AtomicString& VRDisplay::interfaceName() const {
756 return EventTargetNames::VRDisplay; 716 return EventTargetNames::VRDisplay;
757 } 717 }
758 718
(...skipping 16 matching lines...) Expand all
775 visitor->trace(m_stageParameters); 735 visitor->trace(m_stageParameters);
776 visitor->trace(m_eyeParametersLeft); 736 visitor->trace(m_eyeParametersLeft);
777 visitor->trace(m_eyeParametersRight); 737 visitor->trace(m_eyeParametersRight);
778 visitor->trace(m_layer); 738 visitor->trace(m_layer);
779 visitor->trace(m_renderingContext); 739 visitor->trace(m_renderingContext);
780 visitor->trace(m_scriptedAnimationController); 740 visitor->trace(m_scriptedAnimationController);
781 visitor->trace(m_pendingPresentResolvers); 741 visitor->trace(m_pendingPresentResolvers);
782 } 742 }
783 743
784 } // namespace blink 744 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/vr/VRDisplay.h ('k') | third_party/WebKit/Source/modules/vr/VRFrameData.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698