| 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/FrameRequestCallback.h" | 8 #include "core/dom/FrameRequestCallback.h" |
| 9 #include "core/dom/Fullscreen.h" | 9 #include "core/dom/Fullscreen.h" |
| 10 #include "core/dom/ScriptedAnimationController.h" | 10 #include "core/dom/ScriptedAnimationController.h" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 visitor->trace(m_vrDisplay); | 50 visitor->trace(m_vrDisplay); |
| 51 | 51 |
| 52 FrameRequestCallback::trace(visitor); | 52 FrameRequestCallback::trace(visitor); |
| 53 } | 53 } |
| 54 | 54 |
| 55 Member<VRDisplay> m_vrDisplay; | 55 Member<VRDisplay> m_vrDisplay; |
| 56 }; | 56 }; |
| 57 | 57 |
| 58 } // namespace | 58 } // namespace |
| 59 | 59 |
| 60 VRDisplay::VRDisplay(NavigatorVR* navigatorVR) | 60 VRDisplay::VRDisplay(NavigatorVR* navigatorVR, |
| 61 device::mojom::blink::VRDisplayPtr display, |
| 62 device::mojom::blink::VRDisplayClientRequest request) |
| 61 : m_navigatorVR(navigatorVR), | 63 : m_navigatorVR(navigatorVR), |
| 62 m_displayId(0), | |
| 63 m_isConnected(false), | 64 m_isConnected(false), |
| 64 m_isPresenting(false), | 65 m_isPresenting(false), |
| 65 m_canUpdateFramePose(true), | 66 m_canUpdateFramePose(true), |
| 66 m_capabilities(new VRDisplayCapabilities()), | 67 m_capabilities(new VRDisplayCapabilities()), |
| 67 m_eyeParametersLeft(new VREyeParameters()), | 68 m_eyeParametersLeft(new VREyeParameters()), |
| 68 m_eyeParametersRight(new VREyeParameters()), | 69 m_eyeParametersRight(new VREyeParameters()), |
| 69 m_depthNear(0.01), | 70 m_depthNear(0.01), |
| 70 m_depthFar(10000.0), | 71 m_depthFar(10000.0), |
| 71 m_fullscreenCheckTimer(this, &VRDisplay::onFullscreenCheck), | 72 m_fullscreenCheckTimer(this, &VRDisplay::onFullscreenCheck), |
| 72 m_animationCallbackRequested(false), | 73 m_animationCallbackRequested(false), |
| 73 m_inAnimationFrame(false) {} | 74 m_inAnimationFrame(false), |
| 75 m_display(std::move(display)), |
| 76 m_binding(this, std::move(request)) { |
| 77 ThreadState::current()->registerPreFinalizer(this); |
| 78 } |
| 74 | 79 |
| 75 VRDisplay::~VRDisplay() {} | 80 VRDisplay::~VRDisplay() {} |
| 76 | 81 |
| 77 VRController* VRDisplay::controller() { | 82 VRController* VRDisplay::controller() { |
| 78 return m_navigatorVR->controller(); | 83 return m_navigatorVR->controller(); |
| 79 } | 84 } |
| 80 | 85 |
| 81 void VRDisplay::update(const device::blink::VRDisplayPtr& display) { | 86 void VRDisplay::update(const device::mojom::blink::VRDisplayInfoPtr& display) { |
| 82 m_displayId = display->index; | 87 m_displayId = display->index; |
| 83 m_displayName = display->displayName; | 88 m_displayName = display->displayName; |
| 84 m_isConnected = true; | 89 m_isConnected = true; |
| 85 | 90 |
| 86 m_capabilities->setHasOrientation(display->capabilities->hasOrientation); | 91 m_capabilities->setHasOrientation(display->capabilities->hasOrientation); |
| 87 m_capabilities->setHasPosition(display->capabilities->hasPosition); | 92 m_capabilities->setHasPosition(display->capabilities->hasPosition); |
| 88 m_capabilities->setHasExternalDisplay( | 93 m_capabilities->setHasExternalDisplay( |
| 89 display->capabilities->hasExternalDisplay); | 94 display->capabilities->hasExternalDisplay); |
| 90 m_capabilities->setCanPresent(display->capabilities->canPresent); | 95 m_capabilities->setCanPresent(display->capabilities->canPresent); |
| 91 m_capabilities->setMaxLayers(display->capabilities->canPresent ? 1 : 0); | 96 m_capabilities->setMaxLayers(display->capabilities->canPresent ? 1 : 0); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 if (!m_framePose) | 131 if (!m_framePose) |
| 127 return nullptr; | 132 return nullptr; |
| 128 | 133 |
| 129 VRPose* pose = VRPose::create(); | 134 VRPose* pose = VRPose::create(); |
| 130 pose->setPose(m_framePose); | 135 pose->setPose(m_framePose); |
| 131 return pose; | 136 return pose; |
| 132 } | 137 } |
| 133 | 138 |
| 134 void VRDisplay::updatePose() { | 139 void VRDisplay::updatePose() { |
| 135 if (m_canUpdateFramePose) { | 140 if (m_canUpdateFramePose) { |
| 136 m_framePose = controller()->getPose(m_displayId); | 141 if (!m_display) |
| 142 return; |
| 143 device::mojom::blink::VRPosePtr pose; |
| 144 m_display->GetPose(&pose); |
| 145 m_framePose = std::move(pose); |
| 137 if (m_isPresenting) | 146 if (m_isPresenting) |
| 138 m_canUpdateFramePose = false; | 147 m_canUpdateFramePose = false; |
| 139 } | 148 } |
| 140 } | 149 } |
| 141 | 150 |
| 142 void VRDisplay::resetPose() { | 151 void VRDisplay::resetPose() { |
| 143 controller()->resetPose(m_displayId); | 152 if (!m_display) |
| 153 return; |
| 154 |
| 155 m_display->ResetPose(); |
| 144 } | 156 } |
| 145 | 157 |
| 146 VREyeParameters* VRDisplay::getEyeParameters(const String& whichEye) { | 158 VREyeParameters* VRDisplay::getEyeParameters(const String& whichEye) { |
| 147 switch (stringToVREye(whichEye)) { | 159 switch (stringToVREye(whichEye)) { |
| 148 case VREyeLeft: | 160 case VREyeLeft: |
| 149 return m_eyeParametersLeft; | 161 return m_eyeParametersLeft; |
| 150 case VREyeRight: | 162 case VREyeRight: |
| 151 return m_eyeParametersRight; | 163 return m_eyeParametersRight; |
| 152 default: | 164 default: |
| 153 return nullptr; | 165 return nullptr; |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 Fullscreen::requestFullscreen(*m_layer.source(), | 304 Fullscreen::requestFullscreen(*m_layer.source(), |
| 293 Fullscreen::UnprefixedRequest); | 305 Fullscreen::UnprefixedRequest); |
| 294 | 306 |
| 295 // Check to see if the canvas is still the current fullscreen | 307 // Check to see if the canvas is still the current fullscreen |
| 296 // element once per second. | 308 // element once per second. |
| 297 m_fullscreenCheckTimer.startRepeating(1.0, BLINK_FROM_HERE); | 309 m_fullscreenCheckTimer.startRepeating(1.0, BLINK_FROM_HERE); |
| 298 } | 310 } |
| 299 | 311 |
| 300 if (firstPresent) { | 312 if (firstPresent) { |
| 301 bool secureContext = scriptState->getExecutionContext()->isSecureContext(); | 313 bool secureContext = scriptState->getExecutionContext()->isSecureContext(); |
| 302 controller()->requestPresent(resolver, m_displayId, secureContext); | 314 if (!m_display) { |
| 315 DOMException* exception = DOMException::create( |
| 316 InvalidStateError, "The service is no longer active."); |
| 317 resolver->reject(exception); |
| 318 return promise; |
| 319 } |
| 320 m_display->RequestPresent( |
| 321 secureContext, convertToBaseCallback(WTF::bind( |
| 322 &VRDisplay::onPresentComplete, wrapPersistent(this), |
| 323 wrapPersistent(resolver)))); |
| 303 } else { | 324 } else { |
| 304 updateLayerBounds(); | 325 updateLayerBounds(); |
| 305 resolver->resolve(); | 326 resolver->resolve(); |
| 306 ReportPresentationResult(PresentationResult::SuccessAlreadyPresenting); | 327 ReportPresentationResult(PresentationResult::SuccessAlreadyPresenting); |
| 307 } | 328 } |
| 308 | 329 |
| 309 return promise; | 330 return promise; |
| 310 } | 331 } |
| 311 | 332 |
| 333 void VRDisplay::onPresentComplete(ScriptPromiseResolver* resolver, |
| 334 bool success) { |
| 335 if (success) { |
| 336 this->beginPresent(resolver); |
| 337 } else { |
| 338 this->forceExitPresent(); |
| 339 DOMException* exception = DOMException::create( |
| 340 NotAllowedError, "Presentation request was denied."); |
| 341 resolver->reject(exception); |
| 342 } |
| 343 } |
| 344 |
| 312 ScriptPromise VRDisplay::exitPresent(ScriptState* scriptState) { | 345 ScriptPromise VRDisplay::exitPresent(ScriptState* scriptState) { |
| 313 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | 346 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
| 314 ScriptPromise promise = resolver->promise(); | 347 ScriptPromise promise = resolver->promise(); |
| 315 | 348 |
| 316 if (!m_isPresenting) { | 349 if (!m_isPresenting) { |
| 317 // Can't stop presenting if we're not presenting. | 350 // Can't stop presenting if we're not presenting. |
| 318 DOMException* exception = | 351 DOMException* exception = |
| 319 DOMException::create(InvalidStateError, "VRDisplay is not presenting."); | 352 DOMException::create(InvalidStateError, "VRDisplay is not presenting."); |
| 320 resolver->reject(exception); | 353 resolver->reject(exception); |
| 321 return promise; | 354 return promise; |
| 322 } | 355 } |
| 323 | 356 |
| 324 controller()->exitPresent(m_displayId); | 357 if (!m_display) { |
| 358 DOMException* exception = |
| 359 DOMException::create(InvalidStateError, "VRService is not available."); |
| 360 resolver->reject(exception); |
| 361 return promise; |
| 362 } |
| 363 m_display->ExitPresent(); |
| 325 | 364 |
| 326 resolver->resolve(); | 365 resolver->resolve(); |
| 327 | 366 |
| 328 forceExitPresent(); | 367 forceExitPresent(); |
| 329 | 368 |
| 330 return promise; | 369 return promise; |
| 331 } | 370 } |
| 332 | 371 |
| 333 void VRDisplay::beginPresent(ScriptPromiseResolver* resolver) { | 372 void VRDisplay::beginPresent(ScriptPromiseResolver* resolver) { |
| 334 if (m_capabilities->hasExternalDisplay()) { | 373 if (m_capabilities->hasExternalDisplay()) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 361 } | 400 } |
| 362 m_navigatorVR->fireVRDisplayPresentChange(this); | 401 m_navigatorVR->fireVRDisplayPresentChange(this); |
| 363 } | 402 } |
| 364 | 403 |
| 365 m_isPresenting = false; | 404 m_isPresenting = false; |
| 366 m_renderingContext = nullptr; | 405 m_renderingContext = nullptr; |
| 367 m_contextGL = nullptr; | 406 m_contextGL = nullptr; |
| 368 } | 407 } |
| 369 | 408 |
| 370 void VRDisplay::updateLayerBounds() { | 409 void VRDisplay::updateLayerBounds() { |
| 410 if (!m_display) |
| 411 return; |
| 412 |
| 371 // Set up the texture bounds for the provided layer | 413 // Set up the texture bounds for the provided layer |
| 372 device::blink::VRLayerBoundsPtr leftBounds = | 414 device::mojom::blink::VRLayerBoundsPtr leftBounds = |
| 373 device::blink::VRLayerBounds::New(); | 415 device::mojom::blink::VRLayerBounds::New(); |
| 374 device::blink::VRLayerBoundsPtr rightBounds = | 416 device::mojom::blink::VRLayerBoundsPtr rightBounds = |
| 375 device::blink::VRLayerBounds::New(); | 417 device::mojom::blink::VRLayerBounds::New(); |
| 376 | 418 |
| 377 if (m_layer.leftBounds().size() == 4) { | 419 if (m_layer.leftBounds().size() == 4) { |
| 378 leftBounds->left = m_layer.leftBounds()[0]; | 420 leftBounds->left = m_layer.leftBounds()[0]; |
| 379 leftBounds->top = m_layer.leftBounds()[1]; | 421 leftBounds->top = m_layer.leftBounds()[1]; |
| 380 leftBounds->width = m_layer.leftBounds()[2]; | 422 leftBounds->width = m_layer.leftBounds()[2]; |
| 381 leftBounds->height = m_layer.leftBounds()[3]; | 423 leftBounds->height = m_layer.leftBounds()[3]; |
| 382 } else { | 424 } else { |
| 383 // Left eye defaults | 425 // Left eye defaults |
| 384 leftBounds->left = 0.0f; | 426 leftBounds->left = 0.0f; |
| 385 leftBounds->top = 0.0f; | 427 leftBounds->top = 0.0f; |
| 386 leftBounds->width = 0.5f; | 428 leftBounds->width = 0.5f; |
| 387 leftBounds->height = 1.0f; | 429 leftBounds->height = 1.0f; |
| 388 } | 430 } |
| 389 | 431 |
| 390 if (m_layer.rightBounds().size() == 4) { | 432 if (m_layer.rightBounds().size() == 4) { |
| 391 rightBounds->left = m_layer.rightBounds()[0]; | 433 rightBounds->left = m_layer.rightBounds()[0]; |
| 392 rightBounds->top = m_layer.rightBounds()[1]; | 434 rightBounds->top = m_layer.rightBounds()[1]; |
| 393 rightBounds->width = m_layer.rightBounds()[2]; | 435 rightBounds->width = m_layer.rightBounds()[2]; |
| 394 rightBounds->height = m_layer.rightBounds()[3]; | 436 rightBounds->height = m_layer.rightBounds()[3]; |
| 395 } else { | 437 } else { |
| 396 // Right eye defaults | 438 // Right eye defaults |
| 397 rightBounds->left = 0.5f; | 439 rightBounds->left = 0.5f; |
| 398 rightBounds->top = 0.0f; | 440 rightBounds->top = 0.0f; |
| 399 rightBounds->width = 0.5f; | 441 rightBounds->width = 0.5f; |
| 400 rightBounds->height = 1.0f; | 442 rightBounds->height = 1.0f; |
| 401 } | 443 } |
| 402 | 444 |
| 403 controller()->updateLayerBounds(m_displayId, std::move(leftBounds), | 445 m_display->UpdateLayerBounds(std::move(leftBounds), std::move(rightBounds)); |
| 404 std::move(rightBounds)); | |
| 405 } | 446 } |
| 406 | 447 |
| 407 HeapVector<VRLayer> VRDisplay::getLayers() { | 448 HeapVector<VRLayer> VRDisplay::getLayers() { |
| 408 HeapVector<VRLayer> layers; | 449 HeapVector<VRLayer> layers; |
| 409 | 450 |
| 410 if (m_isPresenting) { | 451 if (m_isPresenting) { |
| 411 layers.append(m_layer); | 452 layers.append(m_layer); |
| 412 } | 453 } |
| 413 | 454 |
| 414 return layers; | 455 return layers; |
| 415 } | 456 } |
| 416 | 457 |
| 417 void VRDisplay::submitFrame() { | 458 void VRDisplay::submitFrame() { |
| 459 if (!m_display) |
| 460 return; |
| 461 |
| 418 Document* doc = m_navigatorVR->document(); | 462 Document* doc = m_navigatorVR->document(); |
| 419 if (!m_isPresenting) { | 463 if (!m_isPresenting) { |
| 420 if (doc) { | 464 if (doc) { |
| 421 doc->addConsoleMessage(ConsoleMessage::create( | 465 doc->addConsoleMessage(ConsoleMessage::create( |
| 422 RenderingMessageSource, WarningMessageLevel, | 466 RenderingMessageSource, WarningMessageLevel, |
| 423 "submitFrame has no effect when the VRDisplay is not presenting.")); | 467 "submitFrame has no effect when the VRDisplay is not presenting.")); |
| 424 } | 468 } |
| 425 return; | 469 return; |
| 426 } | 470 } |
| 427 | 471 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 gl->ClearColor((idx & 255) / 255.0f, ((idx >> 8) & 255) / 255.0f, | 505 gl->ClearColor((idx & 255) / 255.0f, ((idx >> 8) & 255) / 255.0f, |
| 462 ((idx >> 16) & 255) / 255.0f, 1.0f); | 506 ((idx >> 16) & 255) / 255.0f, 1.0f); |
| 463 gl->Clear(GL_COLOR_BUFFER_BIT); | 507 gl->Clear(GL_COLOR_BUFFER_BIT); |
| 464 | 508 |
| 465 // Set the GL state back to what was set by the WebVR application. | 509 // Set the GL state back to what was set by the WebVR application. |
| 466 m_renderingContext->restoreScissorEnabled(); | 510 m_renderingContext->restoreScissorEnabled(); |
| 467 m_renderingContext->restoreScissorBox(); | 511 m_renderingContext->restoreScissorBox(); |
| 468 m_renderingContext->restoreColorMask(); | 512 m_renderingContext->restoreColorMask(); |
| 469 m_renderingContext->restoreClearColor(); | 513 m_renderingContext->restoreClearColor(); |
| 470 | 514 |
| 471 controller()->submitFrame(m_displayId, m_framePose.Clone()); | 515 m_display->SubmitFrame(m_framePose.Clone()); |
| 472 m_canUpdateFramePose = true; | 516 m_canUpdateFramePose = true; |
| 473 } | 517 } |
| 474 | 518 |
| 519 void VRDisplay::OnDisplayChanged( |
| 520 device::mojom::blink::VRDisplayInfoPtr display) { |
| 521 update(display); |
| 522 } |
| 523 |
| 524 void VRDisplay::OnExitPresent() { |
| 525 forceExitPresent(); |
| 526 } |
| 527 |
| 528 void VRDisplay::onDisplayConnected() { |
| 529 m_navigatorVR->fireVREvent(VRDisplayEvent::create( |
| 530 EventTypeNames::vrdisplayconnect, true, false, this, "connect")); |
| 531 } |
| 532 |
| 533 void VRDisplay::onDisplayDisconnected() { |
| 534 m_navigatorVR->fireVREvent(VRDisplayEvent::create( |
| 535 EventTypeNames::vrdisplaydisconnect, true, false, this, "disconnect")); |
| 536 } |
| 537 |
| 475 void VRDisplay::onFullscreenCheck(TimerBase*) { | 538 void VRDisplay::onFullscreenCheck(TimerBase*) { |
| 476 // TODO: This is a temporary measure to track if fullscreen mode has been | 539 // TODO: This is a temporary measure to track if fullscreen mode has been |
| 477 // exited by the UA. If so we need to end VR presentation. Soon we won't | 540 // exited by the UA. If so we need to end VR presentation. Soon we won't |
| 478 // depend on the Fullscreen API to fake VR presentation, so this will | 541 // depend on the Fullscreen API to fake VR presentation, so this will |
| 479 // become unnessecary. Until that point, though, this seems preferable to | 542 // become unnessecary. Until that point, though, this seems preferable to |
| 480 // adding a bunch of notification plumbing to Fullscreen. | 543 // adding a bunch of notification plumbing to Fullscreen. |
| 481 if (!Fullscreen::isCurrentFullScreenElement(*m_layer.source())) { | 544 if (!Fullscreen::isCurrentFullScreenElement(*m_layer.source())) { |
| 482 m_isPresenting = false; | 545 m_isPresenting = false; |
| 483 m_navigatorVR->fireVRDisplayPresentChange(this); | 546 m_navigatorVR->fireVRDisplayPresentChange(this); |
| 484 m_fullscreenCheckTimer.stop(); | 547 m_fullscreenCheckTimer.stop(); |
| 485 controller()->exitPresent(m_displayId); | 548 if (!m_display) |
| 549 return; |
| 550 m_display->ExitPresent(); |
| 486 } | 551 } |
| 487 } | 552 } |
| 488 | 553 |
| 489 ScriptedAnimationController& VRDisplay::ensureScriptedAnimationController( | 554 ScriptedAnimationController& VRDisplay::ensureScriptedAnimationController( |
| 490 Document* doc) { | 555 Document* doc) { |
| 491 if (!m_scriptedAnimationController) | 556 if (!m_scriptedAnimationController) |
| 492 m_scriptedAnimationController = ScriptedAnimationController::create(doc); | 557 m_scriptedAnimationController = ScriptedAnimationController::create(doc); |
| 493 | 558 |
| 494 return *m_scriptedAnimationController; | 559 return *m_scriptedAnimationController; |
| 495 } | 560 } |
| 496 | 561 |
| 562 void VRDisplay::dispose() { |
| 563 m_binding.Close(); |
| 564 } |
| 565 |
| 497 DEFINE_TRACE(VRDisplay) { | 566 DEFINE_TRACE(VRDisplay) { |
| 498 visitor->trace(m_navigatorVR); | 567 visitor->trace(m_navigatorVR); |
| 499 visitor->trace(m_capabilities); | 568 visitor->trace(m_capabilities); |
| 500 visitor->trace(m_stageParameters); | 569 visitor->trace(m_stageParameters); |
| 501 visitor->trace(m_eyeParametersLeft); | 570 visitor->trace(m_eyeParametersLeft); |
| 502 visitor->trace(m_eyeParametersRight); | 571 visitor->trace(m_eyeParametersRight); |
| 503 visitor->trace(m_layer); | 572 visitor->trace(m_layer); |
| 504 visitor->trace(m_renderingContext); | 573 visitor->trace(m_renderingContext); |
| 505 visitor->trace(m_scriptedAnimationController); | 574 visitor->trace(m_scriptedAnimationController); |
| 506 } | 575 } |
| 507 | 576 |
| 508 } // namespace blink | 577 } // namespace blink |
| OLD | NEW |