| 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 WebGL script and underlying GL contexts for use by submitFrame(). |
| 209 m_renderingContext = toWebGLRenderingContextBase(renderingContext); |
| 210 m_contextGL = m_renderingContext->contextGL(); |
| 211 |
| 207 if ((m_layer.leftBounds().size() != 0 && m_layer.leftBounds().size() != 4) || | 212 if ((m_layer.leftBounds().size() != 0 && m_layer.leftBounds().size() != 4) || |
| 208 (m_layer.rightBounds().size() != 0 && | 213 (m_layer.rightBounds().size() != 0 && |
| 209 m_layer.rightBounds().size() != 4)) { | 214 m_layer.rightBounds().size() != 4)) { |
| 210 forceExitPresent(); | 215 forceExitPresent(); |
| 211 DOMException* exception = DOMException::create( | 216 DOMException* exception = DOMException::create( |
| 212 InvalidStateError, | 217 InvalidStateError, |
| 213 "Layer bounds must either be an empty array or have 4 values"); | 218 "Layer bounds must either be an empty array or have 4 values"); |
| 214 resolver->reject(exception); | 219 resolver->reject(exception); |
| 215 return promise; | 220 return promise; |
| 216 } | 221 } |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 HeapVector<VRLayer> layers; | 341 HeapVector<VRLayer> layers; |
| 337 | 342 |
| 338 if (m_isPresenting) { | 343 if (m_isPresenting) { |
| 339 layers.append(m_layer); | 344 layers.append(m_layer); |
| 340 } | 345 } |
| 341 | 346 |
| 342 return layers; | 347 return layers; |
| 343 } | 348 } |
| 344 | 349 |
| 345 void VRDisplay::submitFrame() { | 350 void VRDisplay::submitFrame() { |
| 351 // Write the frame number for the pose used into a bottom left pixel block. |
| 352 // It is read by chrome/browser/android/vr_shell/vr_shell.cc to associate |
| 353 // the correct corresponding pose for submission. |
| 354 auto gl = m_contextGL; |
| 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. |
| 359 |
| 360 gl->Enable(GL_SCISSOR_TEST); |
| 361 // Use a few pixels to ensure we get a clean color. The resolution for the |
| 362 // WebGL buffer may not match the final rendered destination size, and |
| 363 // texture filtering could interfere for single pixels. This isn't visible |
| 364 // since the final rendering hides the edges via a vignette effect. |
| 365 gl->Scissor(0, 0, 4, 4); |
| 366 gl->ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
| 367 int idx = m_framePose->poseIndex; |
| 368 // Careful with the arithmetic here. Float color 1.f is equivalent to int 255. |
| 369 gl->ClearColor((idx & 255) / 255.0f, ((idx >> 8) & 255) / 255.0f, |
| 370 ((idx >> 16) & 255) / 255.0f, 1.0f); |
| 371 gl->Clear(GL_COLOR_BUFFER_BIT); |
| 372 |
| 373 // Set the GL state back to what was set by the WebVR application. |
| 374 m_renderingContext->restoreScissorEnabled(); |
| 375 m_renderingContext->restoreScissorBox(); |
| 376 m_renderingContext->restoreColorMask(); |
| 377 m_renderingContext->restoreClearColor(); |
| 378 |
| 346 controller()->submitFrame(m_displayId, m_framePose.Clone()); | 379 controller()->submitFrame(m_displayId, m_framePose.Clone()); |
| 347 m_canUpdateFramePose = true; | 380 m_canUpdateFramePose = true; |
| 348 } | 381 } |
| 349 | 382 |
| 350 void VRDisplay::onFullscreenCheck(TimerBase*) { | 383 void VRDisplay::onFullscreenCheck(TimerBase*) { |
| 351 // TODO: This is a temporary measure to track if fullscreen mode has been | 384 // 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 | 385 // 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 | 386 // depend on the Fullscreen API to fake VR presentation, so this will |
| 354 // become unnessecary. Until that point, though, this seems preferable to | 387 // become unnessecary. Until that point, though, this seems preferable to |
| 355 // adding a bunch of notification plumbing to Fullscreen. | 388 // adding a bunch of notification plumbing to Fullscreen. |
| 356 if (!Fullscreen::isCurrentFullScreenElement(*m_layer.source())) { | 389 if (!Fullscreen::isCurrentFullScreenElement(*m_layer.source())) { |
| 357 m_isPresenting = false; | 390 m_isPresenting = false; |
| 358 m_navigatorVR->fireVRDisplayPresentChange(this); | 391 m_navigatorVR->fireVRDisplayPresentChange(this); |
| 359 m_fullscreenCheckTimer.stop(); | 392 m_fullscreenCheckTimer.stop(); |
| 360 controller()->exitPresent(m_displayId); | 393 controller()->exitPresent(m_displayId); |
| 361 } | 394 } |
| 362 } | 395 } |
| 363 | 396 |
| 364 DEFINE_TRACE(VRDisplay) { | 397 DEFINE_TRACE(VRDisplay) { |
| 365 visitor->trace(m_navigatorVR); | 398 visitor->trace(m_navigatorVR); |
| 366 visitor->trace(m_capabilities); | 399 visitor->trace(m_capabilities); |
| 367 visitor->trace(m_stageParameters); | 400 visitor->trace(m_stageParameters); |
| 368 visitor->trace(m_eyeParametersLeft); | 401 visitor->trace(m_eyeParametersLeft); |
| 369 visitor->trace(m_eyeParametersRight); | 402 visitor->trace(m_eyeParametersRight); |
| 370 visitor->trace(m_layer); | 403 visitor->trace(m_layer); |
| 404 visitor->trace(m_renderingContext); |
| 371 } | 405 } |
| 372 | 406 |
| 373 } // namespace blink | 407 } // namespace blink |
| OLD | NEW |