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

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 10 matching lines...) Expand all
21 #include "modules/vr/VREyeParameters.h" 21 #include "modules/vr/VREyeParameters.h"
22 #include "modules/vr/VRFrameData.h" 22 #include "modules/vr/VRFrameData.h"
23 #include "modules/vr/VRLayer.h" 23 #include "modules/vr/VRLayer.h"
24 #include "modules/vr/VRPose.h" 24 #include "modules/vr/VRPose.h"
25 #include "modules/vr/VRStageParameters.h" 25 #include "modules/vr/VRStageParameters.h"
26 #include "modules/webgl/WebGLRenderingContextBase.h" 26 #include "modules/webgl/WebGLRenderingContextBase.h"
27 #include "platform/Histogram.h" 27 #include "platform/Histogram.h"
28 #include "platform/UserGestureIndicator.h" 28 #include "platform/UserGestureIndicator.h"
29 #include "public/platform/Platform.h" 29 #include "public/platform/Platform.h"
30 #include "wtf/AutoReset.h" 30 #include "wtf/AutoReset.h"
31 #include "wtf/Time.h"
31 32
32 #include <array> 33 #include <array>
33 34
34 namespace blink { 35 namespace blink {
35 36
36 namespace { 37 namespace {
37 38
38 // Magic numbers used to mark valid pose index values encoded in frame 39 // Magic numbers used to mark valid pose index values encoded in frame
39 // data. Must match the magic numbers used in vr_shell.cc. 40 // data. Must match the magic numbers used in vr_shell.cc.
40 static constexpr std::array<uint8_t, 2> kWebVrPosePixelMagicNumbers{{42, 142}}; 41 static constexpr std::array<uint8_t, 2> kWebVrPosePixelMagicNumbers{{42, 142}};
41 42
42 VREye stringToVREye(const String& whichEye) { 43 VREye stringToVREye(const String& whichEye) {
43 if (whichEye == "left") 44 if (whichEye == "left")
44 return VREyeLeft; 45 return VREyeLeft;
45 if (whichEye == "right") 46 if (whichEye == "right")
46 return VREyeRight; 47 return VREyeRight;
47 return VREyeNone; 48 return VREyeNone;
48 } 49 }
49 50
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 51 } // namespace
78 52
79 VRDisplay::VRDisplay(NavigatorVR* navigatorVR, 53 VRDisplay::VRDisplay(NavigatorVR* navigatorVR,
80 device::mojom::blink::VRDisplayPtr display, 54 device::mojom::blink::VRDisplayPtr display,
81 device::mojom::blink::VRDisplayClientRequest request) 55 device::mojom::blink::VRDisplayClientRequest request)
82 : ContextLifecycleObserver(navigatorVR->document()), 56 : ContextLifecycleObserver(navigatorVR->document()),
83 m_navigatorVR(navigatorVR), 57 m_navigatorVR(navigatorVR),
84 m_isConnected(false),
85 m_isPresenting(false),
86 m_isValidDeviceForPresenting(true),
87 m_canUpdateFramePose(true),
88 m_capabilities(new VRDisplayCapabilities()), 58 m_capabilities(new VRDisplayCapabilities()),
89 m_eyeParametersLeft(new VREyeParameters()), 59 m_eyeParametersLeft(new VREyeParameters()),
90 m_eyeParametersRight(new VREyeParameters()), 60 m_eyeParametersRight(new VREyeParameters()),
91 m_depthNear(0.01),
92 m_depthFar(10000.0),
93 m_fullscreenCheckTimer(this, &VRDisplay::onFullscreenCheck), 61 m_fullscreenCheckTimer(this, &VRDisplay::onFullscreenCheck),
94 m_contextGL(nullptr),
95 m_animationCallbackRequested(false),
96 m_inAnimationFrame(false),
97 m_display(std::move(display)), 62 m_display(std::move(display)),
98 m_binding(this, std::move(request)) {} 63 m_displayClientBinding(this, std::move(request)) {}
99 64
100 VRDisplay::~VRDisplay() {} 65 VRDisplay::~VRDisplay() {}
101 66
102 VRController* VRDisplay::controller() { 67 VRController* VRDisplay::controller() {
103 return m_navigatorVR->controller(); 68 return m_navigatorVR->controller();
104 } 69 }
105 70
106 void VRDisplay::update(const device::mojom::blink::VRDisplayInfoPtr& display) { 71 void VRDisplay::update(const device::mojom::blink::VRDisplayInfoPtr& display) {
107 m_displayId = display->index; 72 m_displayId = display->index;
108 m_displayName = display->displayName; 73 m_displayName = display->displayName;
(...skipping 28 matching lines...) Expand all
137 OnPresentChange(); 102 OnPresentChange();
138 } 103 }
139 } 104 }
140 105
141 void VRDisplay::disconnected() { 106 void VRDisplay::disconnected() {
142 if (m_isConnected) 107 if (m_isConnected)
143 m_isConnected = !m_isConnected; 108 m_isConnected = !m_isConnected;
144 } 109 }
145 110
146 bool VRDisplay::getFrameData(VRFrameData* frameData) { 111 bool VRDisplay::getFrameData(VRFrameData* frameData) {
147 updatePose(); 112 if (!m_framePose || m_displayBlurred)
148
149 if (!m_framePose)
150 return false; 113 return false;
151 114
152 if (!frameData) 115 if (!frameData)
153 return false; 116 return false;
154 117
155 if (m_depthNear == m_depthFar) 118 if (m_depthNear == m_depthFar)
156 return false; 119 return false;
157 120
158 return frameData->update(m_framePose, m_eyeParametersLeft, 121 return frameData->update(m_framePose, m_eyeParametersLeft,
159 m_eyeParametersRight, m_depthNear, m_depthFar); 122 m_eyeParametersRight, m_depthNear, m_depthFar);
160 } 123 }
161 124
162 VRPose* VRDisplay::getPose() { 125 VRPose* VRDisplay::getPose() {
163 updatePose(); 126 if (!m_framePose || m_displayBlurred)
164
165 if (!m_framePose)
166 return nullptr; 127 return nullptr;
167 128
168 VRPose* pose = VRPose::create(); 129 VRPose* pose = VRPose::create();
169 pose->setPose(m_framePose); 130 pose->setPose(m_framePose);
170 return pose; 131 return pose;
171 } 132 }
172 133
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() { 134 void VRDisplay::resetPose() {
191 if (!m_display) 135 if (!m_display)
192 return; 136 return;
193 137
194 m_display->ResetPose(); 138 m_display->ResetPose();
195 } 139 }
196 140
197 VREyeParameters* VRDisplay::getEyeParameters(const String& whichEye) { 141 VREyeParameters* VRDisplay::getEyeParameters(const String& whichEye) {
198 switch (stringToVREye(whichEye)) { 142 switch (stringToVREye(whichEye)) {
199 case VREyeLeft: 143 case VREyeLeft:
200 return m_eyeParametersLeft; 144 return m_eyeParametersLeft;
201 case VREyeRight: 145 case VREyeRight:
202 return m_eyeParametersRight; 146 return m_eyeParametersRight;
203 default: 147 default:
204 return nullptr; 148 return nullptr;
205 } 149 }
206 } 150 }
207 151
208 int VRDisplay::requestAnimationFrame(FrameRequestCallback* callback) { 152 int VRDisplay::requestAnimationFrame(FrameRequestCallback* callback) {
209 Document* doc = this->document(); 153 Document* doc = this->document();
210 if (!doc) 154 if (!doc)
211 return 0; 155 return 0;
212 156 m_pendingRaf = true;
213 if (!m_animationCallbackRequested) { 157 if (!m_vrVSyncProvider.is_bound()) {
214 doc->requestAnimationFrame(new VRDisplayFrameRequestCallback(this)); 158 ConnectVSyncProvider();
215 m_animationCallbackRequested = true; 159 } else if (!m_displayBlurred) {
160 m_vrVSyncProvider->GetVSync(convertToBaseCallback(
161 WTF::bind(&VRDisplay::OnVSync, wrapWeakPersistent(this))));
216 } 162 }
217
218 callback->m_useLegacyTimeBase = false; 163 callback->m_useLegacyTimeBase = false;
219 return ensureScriptedAnimationController(doc).registerCallback(callback); 164 return ensureScriptedAnimationController(doc).registerCallback(callback);
220 } 165 }
221 166
222 void VRDisplay::cancelAnimationFrame(int id) { 167 void VRDisplay::cancelAnimationFrame(int id) {
223 if (!m_scriptedAnimationController) 168 if (!m_scriptedAnimationController)
224 return; 169 return;
225 m_scriptedAnimationController->cancelCallback(id); 170 m_scriptedAnimationController->cancelCallback(id);
226 } 171 }
227 172
228 void VRDisplay::OnBlur() { 173 void VRDisplay::OnBlur() {
229 m_displayBlurred = true; 174 m_displayBlurred = true;
230 175 m_vrVSyncProvider.reset();
231 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create( 176 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create(
232 EventTypeNames::vrdisplayblur, true, false, this, "")); 177 EventTypeNames::vrdisplayblur, true, false, this, ""));
233 } 178 }
234 179
235 void VRDisplay::OnFocus() { 180 void VRDisplay::OnFocus() {
236 m_displayBlurred = false; 181 m_displayBlurred = false;
237 // Restart our internal doc requestAnimationFrame callback, if it fired while 182 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( 183 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create(
249 EventTypeNames::vrdisplayfocus, true, false, this, "")); 184 EventTypeNames::vrdisplayfocus, true, false, this, ""));
250 } 185 }
251 186
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) { 187 void ReportPresentationResult(PresentationResult result) {
269 // Note that this is called twice for each call to requestPresent - 188 // Note that this is called twice for each call to requestPresent -
270 // one to declare that requestPresent was called, and one for the 189 // one to declare that requestPresent was called, and one for the
271 // result. 190 // result.
272 DEFINE_STATIC_LOCAL( 191 DEFINE_STATIC_LOCAL(
273 EnumerationHistogram, vrPresentationResultHistogram, 192 EnumerationHistogram, vrPresentationResultHistogram,
274 ("VRDisplayPresentResult", 193 ("VRDisplayPresentResult",
275 static_cast<int>(PresentationResult::PresentationResultMax))); 194 static_cast<int>(PresentationResult::PresentationResultMax)));
276 vrPresentationResultHistogram.count(static_cast<int>(result)); 195 vrPresentationResultHistogram.count(static_cast<int>(result));
277 } 196 }
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 kWebVrPosePixelMagicNumbers[1] / 255.0f, 1.0f); 562 kWebVrPosePixelMagicNumbers[1] / 255.0f, 1.0f);
644 gl->Clear(GL_COLOR_BUFFER_BIT); 563 gl->Clear(GL_COLOR_BUFFER_BIT);
645 564
646 // Set the GL state back to what was set by the WebVR application. 565 // Set the GL state back to what was set by the WebVR application.
647 m_renderingContext->restoreScissorEnabled(); 566 m_renderingContext->restoreScissorEnabled();
648 m_renderingContext->restoreScissorBox(); 567 m_renderingContext->restoreScissorBox();
649 m_renderingContext->restoreColorMask(); 568 m_renderingContext->restoreColorMask();
650 m_renderingContext->restoreClearColor(); 569 m_renderingContext->restoreClearColor();
651 570
652 m_display->SubmitFrame(m_framePose.Clone()); 571 m_display->SubmitFrame(m_framePose.Clone());
653 m_canUpdateFramePose = true;
654 } 572 }
655 573
656 Document* VRDisplay::document() { 574 Document* VRDisplay::document() {
657 return m_navigatorVR->document(); 575 return m_navigatorVR->document();
658 } 576 }
659 577
660 void VRDisplay::OnPresentChange() { 578 void VRDisplay::OnPresentChange() {
661 if (m_isPresenting && !m_isValidDeviceForPresenting) { 579 if (m_isPresenting && !m_isValidDeviceForPresenting) {
662 VLOG(1) << __FUNCTION__ << ": device not valid, not sending event"; 580 VLOG(1) << __FUNCTION__ << ": device not valid, not sending event";
663 return; 581 return;
(...skipping 24 matching lines...) Expand all
688 m_navigatorVR->dispatchVRGestureEvent(VRDisplayEvent::create( 606 m_navigatorVR->dispatchVRGestureEvent(VRDisplayEvent::create(
689 EventTypeNames::vrdisplayactivate, true, false, this, reason)); 607 EventTypeNames::vrdisplayactivate, true, false, this, reason));
690 } 608 }
691 609
692 void VRDisplay::OnDeactivate( 610 void VRDisplay::OnDeactivate(
693 device::mojom::blink::VRDisplayEventReason reason) { 611 device::mojom::blink::VRDisplayEventReason reason) {
694 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create( 612 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create(
695 EventTypeNames::vrdisplaydeactivate, true, false, this, reason)); 613 EventTypeNames::vrdisplaydeactivate, true, false, this, reason));
696 } 614 }
697 615
616 void VRDisplay::OnVSync(device::mojom::blink::VRPosePtr pose,
617 mojo::common::mojom::blink::TimeDeltaPtr time) {
618 WTF::TimeDelta timeDelta =
619 WTF::TimeDelta::FromMicroseconds(time->microseconds);
620 // The VSync provider cannot shut down before replying to pending callbacks,
621 // so it will send a null pose with no timestamp to be ignored.
622 if (pose.is_null() && timeDelta == WTF::TimeDelta()) {
haraken 2017/01/19 00:49:56 Just help me understand: What does 'timeDelta == W
mthiesse 2017/01/19 00:54:04 This is checking that the timeDelta default initia
dcheng 2017/01/19 22:16:11 Can we write this as is_zero()?
mthiesse 2017/01/19 22:56:49 Done.
623 // We need to keep the VSync loop going because we haven't responded to the
624 // previous rAF yet.
625 m_vrVSyncProvider->GetVSync(convertToBaseCallback(
626 WTF::bind(&VRDisplay::OnVSync, wrapWeakPersistent(this))));
627 return;
628 }
629 if (m_displayBlurred)
630 return;
631 if (!m_scriptedAnimationController)
632 return;
633 Document* doc = this->document();
634 if (!doc)
635 return;
636
637 // Ensure a consistent timebase with document rAF.
638 if (m_timebase < 0) {
639 m_timebase = WTF::monotonicallyIncreasingTime() - timeDelta.InSecondsF();
640 }
641
642 AutoReset<bool> animating(&m_inAnimationFrame, true);
643 m_framePose = std::move(pose);
644 m_pendingRaf = false;
645 m_scriptedAnimationController->serviceScriptedAnimations(
646 m_timebase + timeDelta.InSecondsF());
647 }
648
649 void VRDisplay::ConnectVSyncProvider() {
650 m_display->GetVRVSyncProvider(mojo::MakeRequest(&m_vrVSyncProvider));
651 if (m_pendingRaf && !m_displayBlurred) {
652 m_vrVSyncProvider->GetVSync(convertToBaseCallback(
653 WTF::bind(&VRDisplay::OnVSync, wrapWeakPersistent(this))));
654 }
655 }
656
698 void VRDisplay::onFullscreenCheck(TimerBase*) { 657 void VRDisplay::onFullscreenCheck(TimerBase*) {
699 if (!m_isPresenting) { 658 if (!m_isPresenting) {
700 m_fullscreenCheckTimer.stop(); 659 m_fullscreenCheckTimer.stop();
701 return; 660 return;
702 } 661 }
703 // TODO: This is a temporary measure to track if fullscreen mode has been 662 // 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 663 // 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 664 // depend on the Fullscreen API to fake VR presentation, so this will
706 // become unnessecary. Until that point, though, this seems preferable to 665 // become unnessecary. Until that point, though, this seems preferable to
707 // adding a bunch of notification plumbing to Fullscreen. 666 // adding a bunch of notification plumbing to Fullscreen.
(...skipping 25 matching lines...) Expand all
733 692
734 ScriptedAnimationController& VRDisplay::ensureScriptedAnimationController( 693 ScriptedAnimationController& VRDisplay::ensureScriptedAnimationController(
735 Document* doc) { 694 Document* doc) {
736 if (!m_scriptedAnimationController) 695 if (!m_scriptedAnimationController)
737 m_scriptedAnimationController = ScriptedAnimationController::create(doc); 696 m_scriptedAnimationController = ScriptedAnimationController::create(doc);
738 697
739 return *m_scriptedAnimationController; 698 return *m_scriptedAnimationController;
740 } 699 }
741 700
742 void VRDisplay::dispose() { 701 void VRDisplay::dispose() {
743 m_binding.Close(); 702 m_displayClientBinding.Close();
703 m_vrVSyncProvider.reset();
744 } 704 }
745 705
746 ExecutionContext* VRDisplay::getExecutionContext() const { 706 ExecutionContext* VRDisplay::getExecutionContext() const {
747 return ContextLifecycleObserver::getExecutionContext(); 707 return ContextLifecycleObserver::getExecutionContext();
748 } 708 }
749 709
750 const AtomicString& VRDisplay::interfaceName() const { 710 const AtomicString& VRDisplay::interfaceName() const {
751 return EventTargetNames::VRDisplay; 711 return EventTargetNames::VRDisplay;
752 } 712 }
753 713
(...skipping 16 matching lines...) Expand all
770 visitor->trace(m_stageParameters); 730 visitor->trace(m_stageParameters);
771 visitor->trace(m_eyeParametersLeft); 731 visitor->trace(m_eyeParametersLeft);
772 visitor->trace(m_eyeParametersRight); 732 visitor->trace(m_eyeParametersRight);
773 visitor->trace(m_layer); 733 visitor->trace(m_layer);
774 visitor->trace(m_renderingContext); 734 visitor->trace(m_renderingContext);
775 visitor->trace(m_scriptedAnimationController); 735 visitor->trace(m_scriptedAnimationController);
776 visitor->trace(m_pendingPresentResolvers); 736 visitor->trace(m_pendingPresentResolvers);
777 } 737 }
778 738
779 } // namespace blink 739 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698