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

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

Issue 2624633002: Remove Sync GetPose VRService call, implement VRVSyncProvider (Closed)
Patch Set: Address comments 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 m_pendingRaf = true;
213 if (!m_animationCallbackRequested) { 156 if (!m_vrVSyncProvider.is_bound()) {
214 doc->requestAnimationFrame(new VRDisplayFrameRequestCallback(this)); 157 ConnectVSyncProvider();
215 m_animationCallbackRequested = true; 158 } else if (!m_displayBlurred) {
159 m_vrVSyncProvider->GetVSync(convertToBaseCallback(
160 WTF::bind(&VRDisplay::OnVSync, wrapWeakPersistent(this))));
216 } 161 }
217
218 callback->m_useLegacyTimeBase = false; 162 callback->m_useLegacyTimeBase = false;
219 return ensureScriptedAnimationController(doc).registerCallback(callback); 163 return ensureScriptedAnimationController(doc).registerCallback(callback);
220 } 164 }
221 165
222 void VRDisplay::cancelAnimationFrame(int id) { 166 void VRDisplay::cancelAnimationFrame(int id) {
223 if (!m_scriptedAnimationController) 167 if (!m_scriptedAnimationController)
224 return; 168 return;
225 m_scriptedAnimationController->cancelCallback(id); 169 m_scriptedAnimationController->cancelCallback(id);
226 } 170 }
227 171
228 void VRDisplay::OnBlur() { 172 void VRDisplay::OnBlur() {
229 m_displayBlurred = true; 173 m_displayBlurred = true;
230 174 m_vrVSyncProvider.reset();
231 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create( 175 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create(
232 EventTypeNames::vrdisplayblur, true, false, this, "")); 176 EventTypeNames::vrdisplayblur, true, false, this, ""));
233 } 177 }
234 178
235 void VRDisplay::OnFocus() { 179 void VRDisplay::OnFocus() {
236 m_displayBlurred = false; 180 m_displayBlurred = false;
237 // Restart our internal doc requestAnimationFrame callback, if it fired while 181 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( 182 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create(
249 EventTypeNames::vrdisplayfocus, true, false, this, "")); 183 EventTypeNames::vrdisplayfocus, true, false, this, ""));
250 } 184 }
251 185
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) { 186 void ReportPresentationResult(PresentationResult result) {
269 // Note that this is called twice for each call to requestPresent - 187 // Note that this is called twice for each call to requestPresent -
270 // one to declare that requestPresent was called, and one for the 188 // one to declare that requestPresent was called, and one for the
271 // result. 189 // result.
272 DEFINE_STATIC_LOCAL( 190 DEFINE_STATIC_LOCAL(
273 EnumerationHistogram, vrPresentationResultHistogram, 191 EnumerationHistogram, vrPresentationResultHistogram,
274 ("VRDisplayPresentResult", 192 ("VRDisplayPresentResult",
275 static_cast<int>(PresentationResult::PresentationResultMax))); 193 static_cast<int>(PresentationResult::PresentationResultMax)));
276 vrPresentationResultHistogram.count(static_cast<int>(result)); 194 vrPresentationResultHistogram.count(static_cast<int>(result));
277 } 195 }
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 kWebVrPosePixelMagicNumbers[1] / 255.0f, 1.0f); 561 kWebVrPosePixelMagicNumbers[1] / 255.0f, 1.0f);
644 gl->Clear(GL_COLOR_BUFFER_BIT); 562 gl->Clear(GL_COLOR_BUFFER_BIT);
645 563
646 // Set the GL state back to what was set by the WebVR application. 564 // Set the GL state back to what was set by the WebVR application.
647 m_renderingContext->restoreScissorEnabled(); 565 m_renderingContext->restoreScissorEnabled();
648 m_renderingContext->restoreScissorBox(); 566 m_renderingContext->restoreScissorBox();
649 m_renderingContext->restoreColorMask(); 567 m_renderingContext->restoreColorMask();
650 m_renderingContext->restoreClearColor(); 568 m_renderingContext->restoreClearColor();
651 569
652 m_display->SubmitFrame(m_framePose.Clone()); 570 m_display->SubmitFrame(m_framePose.Clone());
653 m_canUpdateFramePose = true;
654 } 571 }
655 572
656 Document* VRDisplay::document() { 573 Document* VRDisplay::document() {
657 return m_navigatorVR->document(); 574 return m_navigatorVR->document();
658 } 575 }
659 576
660 void VRDisplay::OnPresentChange() { 577 void VRDisplay::OnPresentChange() {
661 if (m_isPresenting && !m_isValidDeviceForPresenting) { 578 if (m_isPresenting && !m_isValidDeviceForPresenting) {
662 VLOG(1) << __FUNCTION__ << ": device not valid, not sending event"; 579 VLOG(1) << __FUNCTION__ << ": device not valid, not sending event";
663 return; 580 return;
(...skipping 24 matching lines...) Expand all
688 m_navigatorVR->dispatchVRGestureEvent(VRDisplayEvent::create( 605 m_navigatorVR->dispatchVRGestureEvent(VRDisplayEvent::create(
689 EventTypeNames::vrdisplayactivate, true, false, this, reason)); 606 EventTypeNames::vrdisplayactivate, true, false, this, reason));
690 } 607 }
691 608
692 void VRDisplay::OnDeactivate( 609 void VRDisplay::OnDeactivate(
693 device::mojom::blink::VRDisplayEventReason reason) { 610 device::mojom::blink::VRDisplayEventReason reason) {
694 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create( 611 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create(
695 EventTypeNames::vrdisplaydeactivate, true, false, this, reason)); 612 EventTypeNames::vrdisplaydeactivate, true, false, this, reason));
696 } 613 }
697 614
615 void VRDisplay::OnVSync(device::mojom::blink::VRPosePtr pose,
616 double timeSeconds) {
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_pendingRaf = 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.
haraken 2017/01/15 23:55:04 Won't this have a risk of causing a re-connection
mthiesse 2017/01/16 20:52:57 Yes, removed thanks to dcheng's suggestion.
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 if (m_pendingRaf && !m_displayBlurred) {
655 m_vrVSyncProvider->GetVSync(convertToBaseCallback(
656 WTF::bind(&VRDisplay::OnVSync, wrapWeakPersistent(this))));
657 }
658 }
659
698 void VRDisplay::onFullscreenCheck(TimerBase*) { 660 void VRDisplay::onFullscreenCheck(TimerBase*) {
699 if (!m_isPresenting) { 661 if (!m_isPresenting) {
700 m_fullscreenCheckTimer.stop(); 662 m_fullscreenCheckTimer.stop();
701 return; 663 return;
702 } 664 }
703 // TODO: This is a temporary measure to track if fullscreen mode has been 665 // TODO: This is a temporary measure to track if fullscreen mode has been
704 // exited by the UA. If so we need to end VR presentation. Soon we won't 666 // exited by the UA. If so we need to end VR presentation. Soon we won't
705 // depend on the Fullscreen API to fake VR presentation, so this will 667 // depend on the Fullscreen API to fake VR presentation, so this will
706 // become unnessecary. Until that point, though, this seems preferable to 668 // become unnessecary. Until that point, though, this seems preferable to
707 // adding a bunch of notification plumbing to Fullscreen. 669 // adding a bunch of notification plumbing to Fullscreen.
(...skipping 25 matching lines...) Expand all
733 695
734 ScriptedAnimationController& VRDisplay::ensureScriptedAnimationController( 696 ScriptedAnimationController& VRDisplay::ensureScriptedAnimationController(
735 Document* doc) { 697 Document* doc) {
736 if (!m_scriptedAnimationController) 698 if (!m_scriptedAnimationController)
737 m_scriptedAnimationController = ScriptedAnimationController::create(doc); 699 m_scriptedAnimationController = ScriptedAnimationController::create(doc);
738 700
739 return *m_scriptedAnimationController; 701 return *m_scriptedAnimationController;
740 } 702 }
741 703
742 void VRDisplay::dispose() { 704 void VRDisplay::dispose() {
743 m_binding.Close(); 705 m_displayClientBinding.Close();
706 m_vrVSyncProvider.reset();
744 } 707 }
745 708
746 ExecutionContext* VRDisplay::getExecutionContext() const { 709 ExecutionContext* VRDisplay::getExecutionContext() const {
747 return ContextLifecycleObserver::getExecutionContext(); 710 return ContextLifecycleObserver::getExecutionContext();
748 } 711 }
749 712
750 const AtomicString& VRDisplay::interfaceName() const { 713 const AtomicString& VRDisplay::interfaceName() const {
751 return EventTargetNames::VRDisplay; 714 return EventTargetNames::VRDisplay;
752 } 715 }
753 716
(...skipping 15 matching lines...) Expand all
769 visitor->trace(m_stageParameters); 732 visitor->trace(m_stageParameters);
770 visitor->trace(m_eyeParametersLeft); 733 visitor->trace(m_eyeParametersLeft);
771 visitor->trace(m_eyeParametersRight); 734 visitor->trace(m_eyeParametersRight);
772 visitor->trace(m_layer); 735 visitor->trace(m_layer);
773 visitor->trace(m_renderingContext); 736 visitor->trace(m_renderingContext);
774 visitor->trace(m_scriptedAnimationController); 737 visitor->trace(m_scriptedAnimationController);
775 visitor->trace(m_pendingPresentResolvers); 738 visitor->trace(m_pendingPresentResolvers);
776 } 739 }
777 740
778 } // namespace blink 741 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698