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 "core/dom/DOMException.h" | 7 #include "core/dom/DOMException.h" |
8 #include "core/dom/Fullscreen.h" | |
8 #include "core/inspector/ConsoleMessage.h" | 9 #include "core/inspector/ConsoleMessage.h" |
9 #include "modules/vr/NavigatorVR.h" | 10 #include "modules/vr/NavigatorVR.h" |
10 #include "modules/vr/VRController.h" | 11 #include "modules/vr/VRController.h" |
11 #include "modules/vr/VRDisplayCapabilities.h" | 12 #include "modules/vr/VRDisplayCapabilities.h" |
12 #include "modules/vr/VREyeParameters.h" | 13 #include "modules/vr/VREyeParameters.h" |
13 #include "modules/vr/VRLayer.h" | 14 #include "modules/vr/VRLayer.h" |
14 #include "modules/vr/VRPose.h" | 15 #include "modules/vr/VRPose.h" |
15 #include "modules/vr/VRStageParameters.h" | 16 #include "modules/vr/VRStageParameters.h" |
16 #include "modules/webgl/WebGLRenderingContextBase.h" | 17 #include "modules/webgl/WebGLRenderingContextBase.h" |
17 #include "public/platform/Platform.h" | 18 #include "public/platform/Platform.h" |
(...skipping 15 matching lines...) Expand all Loading... | |
33 | 34 |
34 VRDisplay::VRDisplay(NavigatorVR* navigatorVR) | 35 VRDisplay::VRDisplay(NavigatorVR* navigatorVR) |
35 : m_navigatorVR(navigatorVR) | 36 : m_navigatorVR(navigatorVR) |
36 , m_displayId(0) | 37 , m_displayId(0) |
37 , m_isConnected(false) | 38 , m_isConnected(false) |
38 , m_isPresenting(false) | 39 , m_isPresenting(false) |
39 , m_canUpdateFramePose(true) | 40 , m_canUpdateFramePose(true) |
40 , m_capabilities(new VRDisplayCapabilities()) | 41 , m_capabilities(new VRDisplayCapabilities()) |
41 , m_eyeParametersLeft(new VREyeParameters()) | 42 , m_eyeParametersLeft(new VREyeParameters()) |
42 , m_eyeParametersRight(new VREyeParameters()) | 43 , m_eyeParametersRight(new VREyeParameters()) |
44 , m_fullscreenCheckTimer(this, &VRDisplay::onFullscreenCheck) | |
43 { | 45 { |
44 } | 46 } |
45 | 47 |
46 VRDisplay::~VRDisplay() | 48 VRDisplay::~VRDisplay() |
47 { | 49 { |
48 } | 50 } |
49 | 51 |
50 VRController* VRDisplay::controller() | 52 VRController* VRDisplay::controller() |
51 { | 53 { |
52 return m_navigatorVR->controller(); | 54 return m_navigatorVR->controller(); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
124 { | 126 { |
125 if (Document* document = m_navigatorVR->document()) | 127 if (Document* document = m_navigatorVR->document()) |
126 document->cancelAnimationFrame(id); | 128 document->cancelAnimationFrame(id); |
127 } | 129 } |
128 | 130 |
129 ScriptPromise VRDisplay::requestPresent(ScriptState* scriptState, const HeapVect or<VRLayer>& layers) | 131 ScriptPromise VRDisplay::requestPresent(ScriptState* scriptState, const HeapVect or<VRLayer>& layers) |
130 { | 132 { |
131 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 133 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
132 ScriptPromise promise = resolver->promise(); | 134 ScriptPromise promise = resolver->promise(); |
133 | 135 |
136 m_isPresenting = false; | |
137 | |
134 if (!m_capabilities->canPresent()) { | 138 if (!m_capabilities->canPresent()) { |
135 DOMException* exception = DOMException::create(InvalidStateError, "VRDis play cannot present"); | 139 DOMException* exception = DOMException::create(InvalidStateError, "VRDis play cannot present"); |
136 resolver->reject(exception); | 140 resolver->reject(exception); |
137 return promise; | 141 return promise; |
138 } | 142 } |
139 | 143 |
140 if (layers.size() == 0 || layers.size() > m_capabilities->maxLayers()) { | 144 if (layers.size() == 0 || layers.size() > m_capabilities->maxLayers()) { |
141 DOMException* exception = DOMException::create(InvalidStateError, "Inval id number of layers."); | 145 DOMException* exception = DOMException::create(InvalidStateError, "Inval id number of layers."); |
142 if (m_isPresenting) { | 146 if (m_isPresenting) { |
143 exitPresent(scriptState); | 147 exitPresent(scriptState); |
144 } | 148 } |
145 resolver->reject(exception); | 149 resolver->reject(exception); |
146 return promise; | 150 return promise; |
147 } | 151 } |
148 | 152 |
149 // TODO: Implement VR presentation | 153 m_layer = layers[0]; |
150 NOTIMPLEMENTED(); | |
151 | 154 |
152 DOMException* exception = DOMException::create(InvalidStateError, "VR Presen tation not implemented"); | 155 if (m_layer.source()) { |
153 resolver->reject(exception); | 156 if (!m_capabilities->hasExternalDisplay()) { |
157 // TODO: Need a proper VR compositor, but for the moment on mobile | |
158 // we'll just make the canvas fullscreen so that VrShell can pick it | |
159 // up through the standard (high latency) compositing path. | |
160 Fullscreen::from(m_layer.source()->document()).requestFullscreen(*m_ layer.source(), Fullscreen::UnprefixedRequest); | |
161 | |
162 m_isPresenting = true; | |
163 | |
164 resolver->resolve(); | |
165 | |
166 m_navigatorVR->fireVRDisplayPresentChange(this); | |
167 | |
168 // Check to see if the canvas is still the current fullscreen | |
169 // element once per second. | |
170 m_fullscreenCheckTimer.startRepeating(1.0, BLINK_FROM_HERE); | |
haraken
2016/08/23 00:51:29
It's unfortunate that we need to invoke timers eve
| |
171 } else { | |
172 DOMException* exception = DOMException::create(InvalidStateError, "V R Presentation not implemented for this VRDisplay"); | |
173 resolver->reject(exception); | |
174 } | |
175 } | |
154 | 176 |
155 return promise; | 177 return promise; |
156 } | 178 } |
157 | 179 |
158 ScriptPromise VRDisplay::exitPresent(ScriptState* scriptState) | 180 ScriptPromise VRDisplay::exitPresent(ScriptState* scriptState) |
159 { | 181 { |
160 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 182 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
161 ScriptPromise promise = resolver->promise(); | 183 ScriptPromise promise = resolver->promise(); |
162 | 184 |
163 // Can't stop presenting if we're not presenting. | 185 if (!m_isPresenting) { |
164 DOMException* exception = DOMException::create(InvalidStateError, "VRDisplay is not presenting"); | 186 // Can't stop presenting if we're not presenting. |
165 resolver->reject(exception); | 187 DOMException* exception = DOMException::create(InvalidStateError, "VRDis play is not presenting"); |
188 resolver->reject(exception); | |
189 return promise; | |
190 } | |
191 | |
192 if (!m_capabilities->hasExternalDisplay()) { | |
193 Fullscreen::fullyExitFullscreen(m_layer.source()->document()); | |
194 m_fullscreenCheckTimer.stop(); | |
195 } else { | |
196 // Can't get into this presentation mode, so nothing to do here. | |
197 } | |
198 | |
199 m_isPresenting = false; | |
200 | |
201 // TODO: Resolve when exit is confirmed | |
202 resolver->resolve(); | |
203 | |
204 m_navigatorVR->fireVRDisplayPresentChange(this); | |
205 | |
166 return promise; | 206 return promise; |
167 } | 207 } |
168 | 208 |
169 HeapVector<VRLayer> VRDisplay::getLayers() | 209 HeapVector<VRLayer> VRDisplay::getLayers() |
170 { | 210 { |
171 HeapVector<VRLayer> layers; | 211 HeapVector<VRLayer> layers; |
212 | |
213 if (m_isPresenting) { | |
214 layers.append(m_layer); | |
215 } | |
216 | |
172 return layers; | 217 return layers; |
173 } | 218 } |
174 | 219 |
175 void VRDisplay::submitFrame(VRPose* pose) | 220 void VRDisplay::submitFrame(VRPose* pose) |
176 { | 221 { |
177 NOTIMPLEMENTED(); | 222 if (!pose) { |
223 pose = m_framePose; | |
224 } | |
225 | |
226 // Get last orientation | |
227 float ox = 0.0f, oy = 0.0f, oz = 0.0f, ow = 1.0f; | |
228 if (!pose || pose->orientation()) { | |
229 ox = pose->orientation()->data()[0]; | |
230 oy = pose->orientation()->data()[1]; | |
231 oz = pose->orientation()->data()[2]; | |
232 ow = pose->orientation()->data()[3]; | |
233 } | |
178 } | 234 } |
179 | 235 |
180 void VRDisplay::didProcessTask() | 236 void VRDisplay::didProcessTask() |
181 { | 237 { |
182 // Pose should be stable until control is returned to the user agent. | 238 // Pose should be stable until control is returned to the user agent. |
183 if (!m_canUpdateFramePose) { | 239 if (!m_canUpdateFramePose) { |
184 Platform::current()->currentThread()->removeTaskObserver(this); | 240 Platform::current()->currentThread()->removeTaskObserver(this); |
185 m_canUpdateFramePose = true; | 241 m_canUpdateFramePose = true; |
186 } | 242 } |
187 } | 243 } |
188 | 244 |
245 void VRDisplay::onFullscreenCheck(TimerBase*) | |
246 { | |
247 // TODO: This is a temporary measure to track if fullscreen mode has been | |
248 // exited by the UA. If so we need to end VR presentation. Soon we won't | |
249 // depend on the Fullscreen API to fake VR presentation, so this will | |
250 // become unnessecary. Until that point, though, this seems preferable to | |
251 // adding a bunch of notification plumbing to Fullscreen. | |
252 if (!Fullscreen::isCurrentFullScreenElement(*m_layer.source())) { | |
253 m_isPresenting = false; | |
254 m_navigatorVR->fireVRDisplayPresentChange(this); | |
255 m_fullscreenCheckTimer.stop(); | |
256 } | |
257 } | |
258 | |
189 DEFINE_TRACE(VRDisplay) | 259 DEFINE_TRACE(VRDisplay) |
190 { | 260 { |
191 visitor->trace(m_navigatorVR); | 261 visitor->trace(m_navigatorVR); |
192 visitor->trace(m_capabilities); | 262 visitor->trace(m_capabilities); |
193 visitor->trace(m_stageParameters); | 263 visitor->trace(m_stageParameters); |
194 visitor->trace(m_eyeParametersLeft); | 264 visitor->trace(m_eyeParametersLeft); |
195 visitor->trace(m_eyeParametersRight); | 265 visitor->trace(m_eyeParametersRight); |
196 visitor->trace(m_framePose); | 266 visitor->trace(m_framePose); |
267 visitor->trace(m_layer); | |
197 } | 268 } |
198 | 269 |
199 } // namespace blink | 270 } // namespace blink |
OLD | NEW |