| 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/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 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 m_layer.rightBounds().size() != 4)) { | 358 m_layer.rightBounds().size() != 4)) { |
| 359 forceExitPresent(); | 359 forceExitPresent(); |
| 360 DOMException* exception = DOMException::create( | 360 DOMException* exception = DOMException::create( |
| 361 InvalidStateError, | 361 InvalidStateError, |
| 362 "Layer bounds must either be an empty array or have 4 values"); | 362 "Layer bounds must either be an empty array or have 4 values"); |
| 363 resolver->reject(exception); | 363 resolver->reject(exception); |
| 364 ReportPresentationResult(PresentationResult::InvalidLayerBounds); | 364 ReportPresentationResult(PresentationResult::InvalidLayerBounds); |
| 365 return promise; | 365 return promise; |
| 366 } | 366 } |
| 367 | 367 |
| 368 if (firstPresent) { | 368 if (!m_pendingPresentResolvers.isEmpty()) { |
| 369 // If we are waiting on the results of a previous requestPresent call don't |
| 370 // fire a new request, just cache the resolver and resolve it when the |
| 371 // original request returns. |
| 372 m_pendingPresentResolvers.append(resolver); |
| 373 } else if (firstPresent) { |
| 369 bool secureContext = scriptState->getExecutionContext()->isSecureContext(); | 374 bool secureContext = scriptState->getExecutionContext()->isSecureContext(); |
| 370 if (!m_display) { | 375 if (!m_display) { |
| 371 forceExitPresent(); | 376 forceExitPresent(); |
| 372 DOMException* exception = DOMException::create( | 377 DOMException* exception = DOMException::create( |
| 373 InvalidStateError, "The service is no longer active."); | 378 InvalidStateError, "The service is no longer active."); |
| 374 resolver->reject(exception); | 379 resolver->reject(exception); |
| 375 return promise; | 380 return promise; |
| 376 } | 381 } |
| 377 m_display->RequestPresent( | 382 |
| 378 secureContext, convertToBaseCallback(WTF::bind( | 383 m_pendingPresentResolvers.append(resolver); |
| 379 &VRDisplay::onPresentComplete, wrapPersistent(this), | 384 m_display->RequestPresent(secureContext, convertToBaseCallback(WTF::bind( |
| 380 wrapPersistent(resolver)))); | 385 &VRDisplay::onPresentComplete, |
| 386 wrapPersistent(this)))); |
| 381 } else { | 387 } else { |
| 382 updateLayerBounds(); | 388 updateLayerBounds(); |
| 383 resolver->resolve(); | 389 resolver->resolve(); |
| 384 ReportPresentationResult(PresentationResult::SuccessAlreadyPresenting); | 390 ReportPresentationResult(PresentationResult::SuccessAlreadyPresenting); |
| 385 } | 391 } |
| 386 | 392 |
| 387 return promise; | 393 return promise; |
| 388 } | 394 } |
| 389 | 395 |
| 390 void VRDisplay::onPresentComplete(ScriptPromiseResolver* resolver, | 396 void VRDisplay::onPresentComplete(bool success) { |
| 391 bool success) { | |
| 392 if (success) { | 397 if (success) { |
| 393 this->beginPresent(resolver); | 398 this->beginPresent(); |
| 394 } else { | 399 } else { |
| 395 this->forceExitPresent(); | 400 this->forceExitPresent(); |
| 396 DOMException* exception = DOMException::create( | 401 DOMException* exception = DOMException::create( |
| 397 NotAllowedError, "Presentation request was denied."); | 402 NotAllowedError, "Presentation request was denied."); |
| 398 resolver->reject(exception); | 403 |
| 404 while (!m_pendingPresentResolvers.isEmpty()) { |
| 405 ScriptPromiseResolver* resolver = m_pendingPresentResolvers.takeFirst(); |
| 406 resolver->reject(exception); |
| 407 } |
| 399 } | 408 } |
| 400 } | 409 } |
| 401 | 410 |
| 402 ScriptPromise VRDisplay::exitPresent(ScriptState* scriptState) { | 411 ScriptPromise VRDisplay::exitPresent(ScriptState* scriptState) { |
| 403 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | 412 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
| 404 ScriptPromise promise = resolver->promise(); | 413 ScriptPromise promise = resolver->promise(); |
| 405 | 414 |
| 406 if (!m_isPresenting) { | 415 if (!m_isPresenting) { |
| 407 // Can't stop presenting if we're not presenting. | 416 // Can't stop presenting if we're not presenting. |
| 408 DOMException* exception = | 417 DOMException* exception = |
| (...skipping 10 matching lines...) Expand all Loading... |
| 419 } | 428 } |
| 420 m_display->ExitPresent(); | 429 m_display->ExitPresent(); |
| 421 | 430 |
| 422 resolver->resolve(); | 431 resolver->resolve(); |
| 423 | 432 |
| 424 forceExitPresent(); | 433 forceExitPresent(); |
| 425 | 434 |
| 426 return promise; | 435 return promise; |
| 427 } | 436 } |
| 428 | 437 |
| 429 void VRDisplay::beginPresent(ScriptPromiseResolver* resolver) { | 438 void VRDisplay::beginPresent() { |
| 430 Document* doc = m_navigatorVR->document(); | 439 Document* doc = m_navigatorVR->document(); |
| 431 std::unique_ptr<UserGestureIndicator> gestureIndicator; | 440 std::unique_ptr<UserGestureIndicator> gestureIndicator; |
| 432 if (m_capabilities->hasExternalDisplay()) { | 441 if (m_capabilities->hasExternalDisplay()) { |
| 433 forceExitPresent(); | 442 forceExitPresent(); |
| 434 DOMException* exception = DOMException::create( | 443 DOMException* exception = DOMException::create( |
| 435 InvalidStateError, | 444 InvalidStateError, |
| 436 "VR Presentation not implemented for this VRDisplay."); | 445 "VR Presentation not implemented for this VRDisplay."); |
| 437 resolver->reject(exception); | 446 while (!m_pendingPresentResolvers.isEmpty()) { |
| 447 ScriptPromiseResolver* resolver = m_pendingPresentResolvers.takeFirst(); |
| 448 resolver->reject(exception); |
| 449 } |
| 438 ReportPresentationResult( | 450 ReportPresentationResult( |
| 439 PresentationResult::PresentationNotSupportedByDisplay); | 451 PresentationResult::PresentationNotSupportedByDisplay); |
| 440 return; | 452 return; |
| 441 } else { | 453 } else { |
| 442 // TODO(klausw,crbug.com/655722): Need a proper VR compositor, but | 454 // TODO(klausw,crbug.com/655722): Need a proper VR compositor, but |
| 443 // for the moment on mobile we'll just make the canvas fullscreen | 455 // for the moment on mobile we'll just make the canvas fullscreen |
| 444 // so that VrShell can pick it up through the standard (high | 456 // so that VrShell can pick it up through the standard (high |
| 445 // latency) compositing path. | 457 // latency) compositing path. |
| 446 auto canvas = m_layer.source(); | 458 auto canvas = m_layer.source(); |
| 447 auto inlineStyle = canvas->inlineStyle(); | 459 auto inlineStyle = canvas->inlineStyle(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 if (doc) { | 498 if (doc) { |
| 487 Platform::current()->recordRapporURL("VR.WebVR.PresentSuccess", | 499 Platform::current()->recordRapporURL("VR.WebVR.PresentSuccess", |
| 488 WebURL(doc->url())); | 500 WebURL(doc->url())); |
| 489 } | 501 } |
| 490 | 502 |
| 491 m_isPresenting = true; | 503 m_isPresenting = true; |
| 492 ReportPresentationResult(PresentationResult::Success); | 504 ReportPresentationResult(PresentationResult::Success); |
| 493 | 505 |
| 494 updateLayerBounds(); | 506 updateLayerBounds(); |
| 495 | 507 |
| 496 resolver->resolve(); | 508 while (!m_pendingPresentResolvers.isEmpty()) { |
| 509 ScriptPromiseResolver* resolver = m_pendingPresentResolvers.takeFirst(); |
| 510 resolver->resolve(); |
| 511 } |
| 497 OnPresentChange(); | 512 OnPresentChange(); |
| 498 } | 513 } |
| 499 | 514 |
| 500 void VRDisplay::forceExitPresent() { | 515 void VRDisplay::forceExitPresent() { |
| 501 if (m_isPresenting) { | 516 if (m_isPresenting) { |
| 502 if (!m_capabilities->hasExternalDisplay()) { | 517 if (!m_capabilities->hasExternalDisplay()) { |
| 503 auto canvas = m_layer.source(); | 518 auto canvas = m_layer.source(); |
| 504 Fullscreen::fullyExitFullscreen(canvas->document()); | 519 Fullscreen::fullyExitFullscreen(canvas->document()); |
| 505 m_fullscreenCheckTimer.stop(); | 520 m_fullscreenCheckTimer.stop(); |
| 506 if (!m_fullscreenOrigWidth.isNull()) { | 521 if (!m_fullscreenOrigWidth.isNull()) { |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 728 | 743 |
| 729 DEFINE_TRACE(VRDisplay) { | 744 DEFINE_TRACE(VRDisplay) { |
| 730 visitor->trace(m_navigatorVR); | 745 visitor->trace(m_navigatorVR); |
| 731 visitor->trace(m_capabilities); | 746 visitor->trace(m_capabilities); |
| 732 visitor->trace(m_stageParameters); | 747 visitor->trace(m_stageParameters); |
| 733 visitor->trace(m_eyeParametersLeft); | 748 visitor->trace(m_eyeParametersLeft); |
| 734 visitor->trace(m_eyeParametersRight); | 749 visitor->trace(m_eyeParametersRight); |
| 735 visitor->trace(m_layer); | 750 visitor->trace(m_layer); |
| 736 visitor->trace(m_renderingContext); | 751 visitor->trace(m_renderingContext); |
| 737 visitor->trace(m_scriptedAnimationController); | 752 visitor->trace(m_scriptedAnimationController); |
| 753 visitor->trace(m_pendingPresentResolvers); |
| 738 } | 754 } |
| 739 | 755 |
| 740 } // namespace blink | 756 } // namespace blink |
| OLD | NEW |