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/dom/Fullscreen.h" |
9 #include "core/frame/UseCounter.h" | 9 #include "core/frame/UseCounter.h" |
10 #include "core/inspector/ConsoleMessage.h" | 10 #include "core/inspector/ConsoleMessage.h" |
11 #include "gpu/command_buffer/client/gles2_interface.h" | |
11 #include "modules/vr/NavigatorVR.h" | 12 #include "modules/vr/NavigatorVR.h" |
12 #include "modules/vr/VRController.h" | 13 #include "modules/vr/VRController.h" |
13 #include "modules/vr/VRDisplayCapabilities.h" | 14 #include "modules/vr/VRDisplayCapabilities.h" |
14 #include "modules/vr/VREyeParameters.h" | 15 #include "modules/vr/VREyeParameters.h" |
15 #include "modules/vr/VRFrameData.h" | 16 #include "modules/vr/VRFrameData.h" |
16 #include "modules/vr/VRLayer.h" | 17 #include "modules/vr/VRLayer.h" |
17 #include "modules/vr/VRPose.h" | 18 #include "modules/vr/VRPose.h" |
18 #include "modules/vr/VRStageParameters.h" | 19 #include "modules/vr/VRStageParameters.h" |
19 #include "modules/webgl/WebGLRenderingContextBase.h" | 20 #include "modules/webgl/WebGLRenderingContextBase.h" |
20 #include "platform/UserGestureIndicator.h" | 21 #include "platform/UserGestureIndicator.h" |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
197 m_layer.source()->renderingContext(); | 198 m_layer.source()->renderingContext(); |
198 | 199 |
199 if (!renderingContext || !renderingContext->is3d()) { | 200 if (!renderingContext || !renderingContext->is3d()) { |
200 forceExitPresent(); | 201 forceExitPresent(); |
201 DOMException* exception = DOMException::create( | 202 DOMException* exception = DOMException::create( |
202 InvalidStateError, "Layer source must have a WebGLRenderingContext"); | 203 InvalidStateError, "Layer source must have a WebGLRenderingContext"); |
203 resolver->reject(exception); | 204 resolver->reject(exception); |
204 return promise; | 205 return promise; |
205 } | 206 } |
206 | 207 |
208 // Save the GL context for use by submitFrame(). | |
209 m_contextGL = toWebGLRenderingContextBase(renderingContext)->contextGL(); | |
210 | |
207 if ((m_layer.leftBounds().size() != 0 && m_layer.leftBounds().size() != 4) || | 211 if ((m_layer.leftBounds().size() != 0 && m_layer.leftBounds().size() != 4) || |
208 (m_layer.rightBounds().size() != 0 && | 212 (m_layer.rightBounds().size() != 0 && |
209 m_layer.rightBounds().size() != 4)) { | 213 m_layer.rightBounds().size() != 4)) { |
210 forceExitPresent(); | 214 forceExitPresent(); |
211 DOMException* exception = DOMException::create( | 215 DOMException* exception = DOMException::create( |
212 InvalidStateError, | 216 InvalidStateError, |
213 "Layer bounds must either be an empty array or have 4 values"); | 217 "Layer bounds must either be an empty array or have 4 values"); |
214 resolver->reject(exception); | 218 resolver->reject(exception); |
215 return promise; | 219 return promise; |
216 } | 220 } |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
336 HeapVector<VRLayer> layers; | 340 HeapVector<VRLayer> layers; |
337 | 341 |
338 if (m_isPresenting) { | 342 if (m_isPresenting) { |
339 layers.append(m_layer); | 343 layers.append(m_layer); |
340 } | 344 } |
341 | 345 |
342 return layers; | 346 return layers; |
343 } | 347 } |
344 | 348 |
345 void VRDisplay::submitFrame() { | 349 void VRDisplay::submitFrame() { |
350 // Write the frame number for the pose used into a bottom left pixel block. | |
351 // It is read by chrome/browser/android/vr_shell/vr_shell.cc to associate | |
352 // the correct corresponding pose for submission. | |
353 auto gl = m_contextGL; | |
354 int frame = m_framePose->poseNum; | |
355 | |
356 // We must ensure that the WebGL app's GL state is preserved. We do this by | |
357 // calling low-level GL commands directly so that the rendering context's | |
358 // saved parameters don't get overwritten. When compositing, the rendering | |
359 // context restores the saved parameters in clearIfComposited(). | |
360 | |
361 gl->Enable(GL_SCISSOR_TEST); | |
362 // Use a few pixels to ensure we get a clean color. The resolution for the | |
363 // WebGL buffer may not match the final rendered destination size, and | |
364 // texture filtering could interfere for single pixels. This isn't visible | |
365 // since the final rendering hides the edges via a vignette effect. | |
366 gl->Scissor(0, 0, 4, 4); | |
367 gl->ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | |
368 // Careful with the arithmetic here. Float color 1.f is equivalent to int 255. | |
369 gl->ClearColor((frame & 255) / 255.0f, ((frame >> 8) & 255) / 255.0f, | |
370 ((frame >> 16) & 255) / 255.0f, 1.0f); | |
371 gl->Clear(GL_COLOR_BUFFER_BIT); | |
372 | |
373 // TODO(klausw): If/when we end up bypassing the compositor, we'll likely | |
374 // need to call ctx->restoreStateAfterClear() or equivalent manually here | |
375 // since we'd be bypassing its clearIfComposited() method. | |
bajones
2016/10/04 06:33:57
I'd prefer that we explicitly call restoreStateAft
klausw
2016/10/04 06:47:04
I can do that. restoreStateAfterClear() is a prote
klausw
2016/10/04 17:52:47
I've added a new public method to the rendering co
| |
376 | |
346 controller()->submitFrame(m_displayId, m_framePose.Clone()); | 377 controller()->submitFrame(m_displayId, m_framePose.Clone()); |
347 m_canUpdateFramePose = true; | 378 m_canUpdateFramePose = true; |
348 } | 379 } |
349 | 380 |
350 void VRDisplay::onFullscreenCheck(TimerBase*) { | 381 void VRDisplay::onFullscreenCheck(TimerBase*) { |
351 // TODO: This is a temporary measure to track if fullscreen mode has been | 382 // TODO: This is a temporary measure to track if fullscreen mode has been |
352 // exited by the UA. If so we need to end VR presentation. Soon we won't | 383 // exited by the UA. If so we need to end VR presentation. Soon we won't |
353 // depend on the Fullscreen API to fake VR presentation, so this will | 384 // depend on the Fullscreen API to fake VR presentation, so this will |
354 // become unnessecary. Until that point, though, this seems preferable to | 385 // become unnessecary. Until that point, though, this seems preferable to |
355 // adding a bunch of notification plumbing to Fullscreen. | 386 // adding a bunch of notification plumbing to Fullscreen. |
356 if (!Fullscreen::isCurrentFullScreenElement(*m_layer.source())) { | 387 if (!Fullscreen::isCurrentFullScreenElement(*m_layer.source())) { |
357 m_isPresenting = false; | 388 m_isPresenting = false; |
358 m_navigatorVR->fireVRDisplayPresentChange(this); | 389 m_navigatorVR->fireVRDisplayPresentChange(this); |
359 m_fullscreenCheckTimer.stop(); | 390 m_fullscreenCheckTimer.stop(); |
360 controller()->exitPresent(m_displayId); | 391 controller()->exitPresent(m_displayId); |
361 } | 392 } |
362 } | 393 } |
363 | 394 |
364 DEFINE_TRACE(VRDisplay) { | 395 DEFINE_TRACE(VRDisplay) { |
365 visitor->trace(m_navigatorVR); | 396 visitor->trace(m_navigatorVR); |
366 visitor->trace(m_capabilities); | 397 visitor->trace(m_capabilities); |
367 visitor->trace(m_stageParameters); | 398 visitor->trace(m_stageParameters); |
368 visitor->trace(m_eyeParametersLeft); | 399 visitor->trace(m_eyeParametersLeft); |
369 visitor->trace(m_eyeParametersRight); | 400 visitor->trace(m_eyeParametersRight); |
370 visitor->trace(m_layer); | 401 visitor->trace(m_layer); |
371 } | 402 } |
372 | 403 |
373 } // namespace blink | 404 } // namespace blink |
OLD | NEW |