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

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

Issue 2624633002: Remove Sync GetPose VRService call, implement VRVSyncProvider (Closed)
Patch Set: Finish implementation Created 3 years, 11 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 29 matching lines...) Expand all
40 static constexpr std::array<uint8_t, 2> kWebVrPosePixelMagicNumbers{{42, 142}}; 40 static constexpr std::array<uint8_t, 2> kWebVrPosePixelMagicNumbers{{42, 142}};
41 41
42 VREye stringToVREye(const String& whichEye) { 42 VREye stringToVREye(const String& whichEye) {
43 if (whichEye == "left") 43 if (whichEye == "left")
44 return VREyeLeft; 44 return VREyeLeft;
45 if (whichEye == "right") 45 if (whichEye == "right")
46 return VREyeRight; 46 return VREyeRight;
47 return VREyeNone; 47 return VREyeNone;
48 } 48 }
49 49
50 class VRDisplayFrameRequestCallback : public FrameRequestCallback {
51 public:
52 VRDisplayFrameRequestCallback(VRDisplay* vrDisplay) : m_vrDisplay(vrDisplay) {
53 m_useLegacyTimeBase = true;
54 }
55 ~VRDisplayFrameRequestCallback() override {}
56 void handleEvent(double highResTimeMs) override {
57 Document* doc = m_vrDisplay->document();
58 if (!doc)
59 return;
60
61 // Need to divide by 1000 here because serviceScriptedAnimations expects
62 // time to be given in seconds.
63 m_vrDisplay->serviceScriptedAnimations(
64 doc->loader()->timing().pseudoWallTimeToMonotonicTime(highResTimeMs /
65 1000.0));
66 }
67
68 DEFINE_INLINE_VIRTUAL_TRACE() {
69 visitor->trace(m_vrDisplay);
70
71 FrameRequestCallback::trace(visitor);
72 }
73
74 Member<VRDisplay> m_vrDisplay;
75 };
76
77 } // namespace 50 } // namespace
78 51
79 VRDisplay::VRDisplay(NavigatorVR* navigatorVR, 52 VRDisplay::VRDisplay(NavigatorVR* navigatorVR,
80 device::mojom::blink::VRDisplayPtr display, 53 device::mojom::blink::VRDisplayPtr display,
81 device::mojom::blink::VRDisplayClientRequest request) 54 device::mojom::blink::VRDisplayClientRequest request)
82 : ContextLifecycleObserver(navigatorVR->document()), 55 : ContextLifecycleObserver(navigatorVR->document()),
83 m_navigatorVR(navigatorVR), 56 m_navigatorVR(navigatorVR),
84 m_isConnected(false),
85 m_isPresenting(false),
86 m_isValidDeviceForPresenting(true),
87 m_canUpdateFramePose(true),
88 m_capabilities(new VRDisplayCapabilities()), 57 m_capabilities(new VRDisplayCapabilities()),
89 m_eyeParametersLeft(new VREyeParameters()), 58 m_eyeParametersLeft(new VREyeParameters()),
90 m_eyeParametersRight(new VREyeParameters()), 59 m_eyeParametersRight(new VREyeParameters()),
91 m_depthNear(0.01),
92 m_depthFar(10000.0),
93 m_fullscreenCheckTimer(this, &VRDisplay::onFullscreenCheck), 60 m_fullscreenCheckTimer(this, &VRDisplay::onFullscreenCheck),
94 m_contextGL(nullptr),
95 m_animationCallbackRequested(false),
96 m_inAnimationFrame(false),
97 m_display(std::move(display)), 61 m_display(std::move(display)),
98 m_binding(this, std::move(request)) {} 62 m_displayClientBinding(this, std::move(request)) {}
99 63
100 VRDisplay::~VRDisplay() {} 64 VRDisplay::~VRDisplay() {}
101 65
102 VRController* VRDisplay::controller() { 66 VRController* VRDisplay::controller() {
103 return m_navigatorVR->controller(); 67 return m_navigatorVR->controller();
104 } 68 }
105 69
106 void VRDisplay::update(const device::mojom::blink::VRDisplayInfoPtr& display) { 70 void VRDisplay::update(const device::mojom::blink::VRDisplayInfoPtr& display) {
107 m_displayId = display->index; 71 m_displayId = display->index;
108 m_displayName = display->displayName; 72 m_displayName = display->displayName;
(...skipping 28 matching lines...) Expand all
137 OnPresentChange(); 101 OnPresentChange();
138 } 102 }
139 } 103 }
140 104
141 void VRDisplay::disconnected() { 105 void VRDisplay::disconnected() {
142 if (m_isConnected) 106 if (m_isConnected)
143 m_isConnected = !m_isConnected; 107 m_isConnected = !m_isConnected;
144 } 108 }
145 109
146 bool VRDisplay::getFrameData(VRFrameData* frameData) { 110 bool VRDisplay::getFrameData(VRFrameData* frameData) {
147 updatePose(); 111 if (!m_framePose || m_displayBlurred)
148
149 if (!m_framePose)
150 return false; 112 return false;
151 113
152 if (!frameData) 114 if (!frameData)
153 return false; 115 return false;
154 116
155 if (m_depthNear == m_depthFar) 117 if (m_depthNear == m_depthFar)
156 return false; 118 return false;
157 119
158 return frameData->update(m_framePose, m_eyeParametersLeft, 120 return frameData->update(m_framePose, m_eyeParametersLeft,
159 m_eyeParametersRight, m_depthNear, m_depthFar); 121 m_eyeParametersRight, m_depthNear, m_depthFar);
160 } 122 }
161 123
162 VRPose* VRDisplay::getPose() { 124 VRPose* VRDisplay::getPose() {
163 updatePose(); 125 if (!m_framePose || m_displayBlurred)
164
165 if (!m_framePose)
166 return nullptr; 126 return nullptr;
167 127
168 VRPose* pose = VRPose::create(); 128 VRPose* pose = VRPose::create();
169 pose->setPose(m_framePose); 129 pose->setPose(m_framePose);
170 return pose; 130 return pose;
171 } 131 }
172 132
173 void VRDisplay::updatePose() {
174 if (m_displayBlurred) {
175 // WebVR spec says to return a null pose when the display is blurred.
176 m_framePose = nullptr;
177 return;
178 }
179 if (m_canUpdateFramePose) {
180 if (!m_display)
181 return;
182 device::mojom::blink::VRPosePtr pose;
183 m_display->GetPose(&pose);
184 m_framePose = std::move(pose);
185 if (m_isPresenting)
186 m_canUpdateFramePose = false;
187 }
188 }
189
190 void VRDisplay::resetPose() { 133 void VRDisplay::resetPose() {
191 if (!m_display) 134 if (!m_display)
192 return; 135 return;
193 136
194 m_display->ResetPose(); 137 m_display->ResetPose();
195 } 138 }
196 139
197 VREyeParameters* VRDisplay::getEyeParameters(const String& whichEye) { 140 VREyeParameters* VRDisplay::getEyeParameters(const String& whichEye) {
198 switch (stringToVREye(whichEye)) { 141 switch (stringToVREye(whichEye)) {
199 case VREyeLeft: 142 case VREyeLeft:
200 return m_eyeParametersLeft; 143 return m_eyeParametersLeft;
201 case VREyeRight: 144 case VREyeRight:
202 return m_eyeParametersRight; 145 return m_eyeParametersRight;
203 default: 146 default:
204 return nullptr; 147 return nullptr;
205 } 148 }
206 } 149 }
207 150
208 int VRDisplay::requestAnimationFrame(FrameRequestCallback* callback) { 151 int VRDisplay::requestAnimationFrame(FrameRequestCallback* callback) {
209 Document* doc = this->document(); 152 Document* doc = this->document();
210 if (!doc) 153 if (!doc)
211 return 0; 154 return 0;
212 155 if (!m_vrVSyncProvider.is_bound() && !m_displayBlurred) {
213 if (!m_animationCallbackRequested) { 156 ConnectVSyncProvider();
214 doc->requestAnimationFrame(new VRDisplayFrameRequestCallback(this));
215 m_animationCallbackRequested = true;
216 } 157 }
217
218 callback->m_useLegacyTimeBase = false; 158 callback->m_useLegacyTimeBase = false;
219 return ensureScriptedAnimationController(doc).registerCallback(callback); 159 return ensureScriptedAnimationController(doc).registerCallback(callback);
220 } 160 }
221 161
222 void VRDisplay::cancelAnimationFrame(int id) { 162 void VRDisplay::cancelAnimationFrame(int id) {
223 if (!m_scriptedAnimationController) 163 if (!m_scriptedAnimationController)
224 return; 164 return;
225 m_scriptedAnimationController->cancelCallback(id); 165 m_scriptedAnimationController->cancelCallback(id);
226 } 166 }
227 167
228 void VRDisplay::OnBlur() { 168 void VRDisplay::OnBlur() {
229 m_displayBlurred = true; 169 m_displayBlurred = true;
230 170 m_vrVSyncProvider.reset();
231 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create( 171 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create(
232 EventTypeNames::vrdisplayblur, true, false, this, "")); 172 EventTypeNames::vrdisplayblur, true, false, this, ""));
233 } 173 }
234 174
235 void VRDisplay::OnFocus() { 175 void VRDisplay::OnFocus() {
236 m_displayBlurred = false; 176 m_displayBlurred = false;
237 // Restart our internal doc requestAnimationFrame callback, if it fired while 177 ConnectVSyncProvider();
238 // the display was blurred.
239 // TODO(bajones): Don't use doc->requestAnimationFrame() at all. Animation
240 // frames should be tied to the presenting VR display (e.g. should be serviced
241 // by GVR library callbacks on Android), and not the doc frame rate.
242 if (!m_animationCallbackRequested) {
243 Document* doc = this->document();
244 if (!doc)
245 return;
246 doc->requestAnimationFrame(new VRDisplayFrameRequestCallback(this));
247 }
248 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create( 178 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create(
249 EventTypeNames::vrdisplayfocus, true, false, this, "")); 179 EventTypeNames::vrdisplayfocus, true, false, this, ""));
250 } 180 }
251 181
252 void VRDisplay::serviceScriptedAnimations(double monotonicAnimationStartTime) {
253 if (!m_scriptedAnimationController)
254 return;
255 AutoReset<bool> animating(&m_inAnimationFrame, true);
256 m_animationCallbackRequested = false;
257
258 // We use an internal rAF callback to run the animation loop at the display
259 // speed, and run the user's callback after our internal callback fires.
260 // However, when the display is blurred, we want to pause the animation loop,
261 // so we don't fire the user's callback until the display is focused.
262 if (m_displayBlurred)
263 return;
264 m_scriptedAnimationController->serviceScriptedAnimations(
265 monotonicAnimationStartTime);
266 }
267
268 void ReportPresentationResult(PresentationResult result) { 182 void ReportPresentationResult(PresentationResult result) {
269 // Note that this is called twice for each call to requestPresent - 183 // Note that this is called twice for each call to requestPresent -
270 // one to declare that requestPresent was called, and one for the 184 // one to declare that requestPresent was called, and one for the
271 // result. 185 // result.
272 DEFINE_STATIC_LOCAL( 186 DEFINE_STATIC_LOCAL(
273 EnumerationHistogram, vrPresentationResultHistogram, 187 EnumerationHistogram, vrPresentationResultHistogram,
274 ("VRDisplayPresentResult", 188 ("VRDisplayPresentResult",
275 static_cast<int>(PresentationResult::PresentationResultMax))); 189 static_cast<int>(PresentationResult::PresentationResultMax)));
276 vrPresentationResultHistogram.count(static_cast<int>(result)); 190 vrPresentationResultHistogram.count(static_cast<int>(result));
277 } 191 }
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 m_navigatorVR->dispatchVRGestureEvent(VRDisplayEvent::create( 601 m_navigatorVR->dispatchVRGestureEvent(VRDisplayEvent::create(
688 EventTypeNames::vrdisplayactivate, true, false, this, reason)); 602 EventTypeNames::vrdisplayactivate, true, false, this, reason));
689 } 603 }
690 604
691 void VRDisplay::OnDeactivate( 605 void VRDisplay::OnDeactivate(
692 device::mojom::blink::VRDisplayEventReason reason) { 606 device::mojom::blink::VRDisplayEventReason reason) {
693 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create( 607 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create(
694 EventTypeNames::vrdisplaydeactivate, true, false, this, reason)); 608 EventTypeNames::vrdisplaydeactivate, true, false, this, reason));
695 } 609 }
696 610
611 void VRDisplay::OnVSync(device::mojom::blink::VRPosePtr pose,
612 double timeSeconds) {
613 if (m_vrVSyncProvider.is_bound()) {
614 m_vrVSyncProvider->GetVSync(convertToBaseCallback(
615 WTF::bind(&VRDisplay::OnVSync, wrapWeakPersistent(this))));
616 }
617 // The VSync provider cannot shut down before replying to pending callbacks,
618 // so it will send a null pose with no timestamp to be ignored.
619 if (pose.is_null() && timeSeconds == 0)
620 return;
621 if (m_displayBlurred)
622 return;
623 if (!m_scriptedAnimationController)
624 return;
625 Document* doc = this->document();
626 if (!doc)
627 return;
628
629 // Ensure a consistent timebase with document rAF.
630 if (m_timebase < 0) {
631 m_timebase = WTF::monotonicallyIncreasingTime() - timeSeconds;
632 }
633
634 AutoReset<bool> animating(&m_inAnimationFrame, true);
635 m_framePose = std::move(pose);
636 m_canUpdateFramePose = false;
637 m_scriptedAnimationController->serviceScriptedAnimations(m_timebase +
638 timeSeconds);
639 }
640
641 void VRDisplay::OnVSyncProviderDisconnected() {
642 TaskRunnerHelper::get(TaskType::UnspecedTimer, document())
643 ->postDelayedTask(
644 BLINK_FROM_HERE,
645 WTF::bind(&VRDisplay::ConnectVSyncProvider, wrapWeakPersistent(this)),
646 100); // Short delay to throttle requests.
dcheng 2017/01/12 09:56:56 My understanding is the impl side is hosted in the
mthiesse 2017/01/12 15:49:03 No, this pipe shutting down doesn't indicate the b
dcheng 2017/01/14 11:22:53 You can use mojo::Binding<T>::Unbind() to get an I
mthiesse 2017/01/16 20:52:57 Ah thanks, that's exactly what I was looking for a
647 }
648
649 void VRDisplay::ConnectVSyncProvider() {
650 m_display->GetVRVSyncProvider(mojo::MakeRequest(&m_vrVSyncProvider));
651 m_vrVSyncProvider.set_connection_error_handler(
652 convertToBaseCallback(WTF::bind(&VRDisplay::OnVSyncProviderDisconnected,
653 wrapWeakPersistent(this))));
654 m_vrVSyncProvider->GetVSync(convertToBaseCallback(
655 WTF::bind(&VRDisplay::OnVSync, wrapWeakPersistent(this))));
656 }
657
697 void VRDisplay::onFullscreenCheck(TimerBase*) { 658 void VRDisplay::onFullscreenCheck(TimerBase*) {
698 if (!m_isPresenting) { 659 if (!m_isPresenting) {
699 m_fullscreenCheckTimer.stop(); 660 m_fullscreenCheckTimer.stop();
700 return; 661 return;
701 } 662 }
702 // TODO: This is a temporary measure to track if fullscreen mode has been 663 // TODO: This is a temporary measure to track if fullscreen mode has been
703 // exited by the UA. If so we need to end VR presentation. Soon we won't 664 // exited by the UA. If so we need to end VR presentation. Soon we won't
704 // depend on the Fullscreen API to fake VR presentation, so this will 665 // depend on the Fullscreen API to fake VR presentation, so this will
705 // become unnessecary. Until that point, though, this seems preferable to 666 // become unnessecary. Until that point, though, this seems preferable to
706 // adding a bunch of notification plumbing to Fullscreen. 667 // adding a bunch of notification plumbing to Fullscreen.
(...skipping 25 matching lines...) Expand all
732 693
733 ScriptedAnimationController& VRDisplay::ensureScriptedAnimationController( 694 ScriptedAnimationController& VRDisplay::ensureScriptedAnimationController(
734 Document* doc) { 695 Document* doc) {
735 if (!m_scriptedAnimationController) 696 if (!m_scriptedAnimationController)
736 m_scriptedAnimationController = ScriptedAnimationController::create(doc); 697 m_scriptedAnimationController = ScriptedAnimationController::create(doc);
737 698
738 return *m_scriptedAnimationController; 699 return *m_scriptedAnimationController;
739 } 700 }
740 701
741 void VRDisplay::dispose() { 702 void VRDisplay::dispose() {
742 m_binding.Close(); 703 m_displayClientBinding.Close();
704 m_vrVSyncProvider.reset();
743 } 705 }
744 706
745 ExecutionContext* VRDisplay::getExecutionContext() const { 707 ExecutionContext* VRDisplay::getExecutionContext() const {
746 return ContextLifecycleObserver::getExecutionContext(); 708 return ContextLifecycleObserver::getExecutionContext();
747 } 709 }
748 710
749 const AtomicString& VRDisplay::interfaceName() const { 711 const AtomicString& VRDisplay::interfaceName() const {
750 return EventTargetNames::VRDisplay; 712 return EventTargetNames::VRDisplay;
751 } 713 }
752 714
(...skipping 15 matching lines...) Expand all
768 visitor->trace(m_stageParameters); 730 visitor->trace(m_stageParameters);
769 visitor->trace(m_eyeParametersLeft); 731 visitor->trace(m_eyeParametersLeft);
770 visitor->trace(m_eyeParametersRight); 732 visitor->trace(m_eyeParametersRight);
771 visitor->trace(m_layer); 733 visitor->trace(m_layer);
772 visitor->trace(m_renderingContext); 734 visitor->trace(m_renderingContext);
773 visitor->trace(m_scriptedAnimationController); 735 visitor->trace(m_scriptedAnimationController);
774 visitor->trace(m_pendingPresentResolvers); 736 visitor->trace(m_pendingPresentResolvers);
775 } 737 }
776 738
777 } // namespace blink 739 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698