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/FrameRequestCallback.h" | 10 #include "core/dom/FrameRequestCallback.h" |
10 #include "core/dom/Fullscreen.h" | 11 #include "core/dom/Fullscreen.h" |
11 #include "core/dom/ScriptedAnimationController.h" | 12 #include "core/dom/ScriptedAnimationController.h" |
12 #include "core/frame/UseCounter.h" | 13 #include "core/frame/UseCounter.h" |
13 #include "core/inspector/ConsoleMessage.h" | 14 #include "core/inspector/ConsoleMessage.h" |
14 #include "gpu/command_buffer/client/gles2_interface.h" | 15 #include "gpu/command_buffer/client/gles2_interface.h" |
15 #include "modules/vr/NavigatorVR.h" | 16 #include "modules/vr/NavigatorVR.h" |
16 #include "modules/vr/VRController.h" | 17 #include "modules/vr/VRController.h" |
17 #include "modules/vr/VRDisplayCapabilities.h" | 18 #include "modules/vr/VRDisplayCapabilities.h" |
18 #include "modules/vr/VREyeParameters.h" | 19 #include "modules/vr/VREyeParameters.h" |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 m_layer.rightBounds().size() != 4)) { | 330 m_layer.rightBounds().size() != 4)) { |
330 forceExitPresent(); | 331 forceExitPresent(); |
331 DOMException* exception = DOMException::create( | 332 DOMException* exception = DOMException::create( |
332 InvalidStateError, | 333 InvalidStateError, |
333 "Layer bounds must either be an empty array or have 4 values"); | 334 "Layer bounds must either be an empty array or have 4 values"); |
334 resolver->reject(exception); | 335 resolver->reject(exception); |
335 ReportPresentationResult(PresentationResult::InvalidLayerBounds); | 336 ReportPresentationResult(PresentationResult::InvalidLayerBounds); |
336 return promise; | 337 return promise; |
337 } | 338 } |
338 | 339 |
339 if (!m_capabilities->hasExternalDisplay()) { | |
340 // TODO(klausw,crbug.com/655722): Need a proper VR compositor, but | |
341 // for the moment on mobile we'll just make the canvas fullscreen | |
342 // so that VrShell can pick it up through the standard (high | |
343 // latency) compositing path. | |
344 auto canvas = m_layer.source(); | |
345 auto inlineStyle = canvas->inlineStyle(); | |
346 if (inlineStyle) { | |
347 // THREE.js's VREffect sets explicit style.width/height on its rendering | |
348 // canvas based on the non-fullscreen window dimensions, and it keeps | |
349 // those unchanged when presenting. Unfortunately it appears that a | |
350 // fullscreened canvas just gets centered if it has explicitly set a | |
351 // size smaller than the fullscreen dimensions. Manually set size to | |
352 // 100% in this case and restore it when exiting fullscreen. This is a | |
353 // stopgap measure since THREE.js's usage appears legal according to the | |
354 // WebVR API spec. This will no longer be necessary once we can get rid | |
355 // of this fullscreen hack. | |
356 m_fullscreenOrigWidth = inlineStyle->getPropertyValue(CSSPropertyWidth); | |
357 if (!m_fullscreenOrigWidth.isNull()) { | |
358 canvas->setInlineStyleProperty(CSSPropertyWidth, "100%"); | |
359 } | |
360 m_fullscreenOrigHeight = inlineStyle->getPropertyValue(CSSPropertyHeight); | |
361 if (!m_fullscreenOrigHeight.isNull()) { | |
362 canvas->setInlineStyleProperty(CSSPropertyHeight, "100%"); | |
363 } | |
364 } else { | |
365 m_fullscreenOrigWidth = String(); | |
366 m_fullscreenOrigHeight = String(); | |
367 } | |
368 Fullscreen::requestFullscreen(*canvas, Fullscreen::UnprefixedRequest); | |
369 | |
370 // Check to see if the canvas is still the current fullscreen | |
371 // element once per second. | |
372 m_fullscreenCheckTimer.startRepeating(1.0, BLINK_FROM_HERE); | |
373 } | |
374 | |
375 if (firstPresent) { | 340 if (firstPresent) { |
376 bool secureContext = scriptState->getExecutionContext()->isSecureContext(); | 341 bool secureContext = scriptState->getExecutionContext()->isSecureContext(); |
377 if (!m_display) { | 342 if (!m_display) { |
378 forceExitPresent(); | 343 forceExitPresent(); |
379 DOMException* exception = DOMException::create( | 344 DOMException* exception = DOMException::create( |
380 InvalidStateError, "The service is no longer active."); | 345 InvalidStateError, "The service is no longer active."); |
381 resolver->reject(exception); | 346 resolver->reject(exception); |
382 return promise; | 347 return promise; |
383 } | 348 } |
384 m_display->RequestPresent( | 349 m_display->RequestPresent( |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 m_display->ExitPresent(); | 392 m_display->ExitPresent(); |
428 | 393 |
429 resolver->resolve(); | 394 resolver->resolve(); |
430 | 395 |
431 forceExitPresent(); | 396 forceExitPresent(); |
432 | 397 |
433 return promise; | 398 return promise; |
434 } | 399 } |
435 | 400 |
436 void VRDisplay::beginPresent(ScriptPromiseResolver* resolver) { | 401 void VRDisplay::beginPresent(ScriptPromiseResolver* resolver) { |
| 402 Document* doc = m_navigatorVR->document(); |
| 403 std::unique_ptr<UserGestureIndicator> gestureIndicator; |
437 if (m_capabilities->hasExternalDisplay()) { | 404 if (m_capabilities->hasExternalDisplay()) { |
438 forceExitPresent(); | 405 forceExitPresent(); |
439 DOMException* exception = DOMException::create( | 406 DOMException* exception = DOMException::create( |
440 InvalidStateError, | 407 InvalidStateError, |
441 "VR Presentation not implemented for this VRDisplay."); | 408 "VR Presentation not implemented for this VRDisplay."); |
442 resolver->reject(exception); | 409 resolver->reject(exception); |
443 ReportPresentationResult( | 410 ReportPresentationResult( |
444 PresentationResult::PresentationNotSupportedByDisplay); | 411 PresentationResult::PresentationNotSupportedByDisplay); |
445 return; | 412 return; |
| 413 } else { |
| 414 // TODO(klausw,crbug.com/655722): Need a proper VR compositor, but |
| 415 // for the moment on mobile we'll just make the canvas fullscreen |
| 416 // so that VrShell can pick it up through the standard (high |
| 417 // latency) compositing path. |
| 418 auto canvas = m_layer.source(); |
| 419 auto inlineStyle = canvas->inlineStyle(); |
| 420 if (inlineStyle) { |
| 421 // THREE.js's VREffect sets explicit style.width/height on its rendering |
| 422 // canvas based on the non-fullscreen window dimensions, and it keeps |
| 423 // those unchanged when presenting. Unfortunately it appears that a |
| 424 // fullscreened canvas just gets centered if it has explicitly set a |
| 425 // size smaller than the fullscreen dimensions. Manually set size to |
| 426 // 100% in this case and restore it when exiting fullscreen. This is a |
| 427 // stopgap measure since THREE.js's usage appears legal according to the |
| 428 // WebVR API spec. This will no longer be necessary once we can get rid |
| 429 // of this fullscreen hack. |
| 430 m_fullscreenOrigWidth = inlineStyle->getPropertyValue(CSSPropertyWidth); |
| 431 if (!m_fullscreenOrigWidth.isNull()) { |
| 432 canvas->setInlineStyleProperty(CSSPropertyWidth, "100%"); |
| 433 } |
| 434 m_fullscreenOrigHeight = inlineStyle->getPropertyValue(CSSPropertyHeight); |
| 435 if (!m_fullscreenOrigHeight.isNull()) { |
| 436 canvas->setInlineStyleProperty(CSSPropertyHeight, "100%"); |
| 437 } |
| 438 } else { |
| 439 m_fullscreenOrigWidth = String(); |
| 440 m_fullscreenOrigHeight = String(); |
| 441 } |
| 442 |
| 443 if (doc) { |
| 444 // Since the callback for requestPresent is asynchronous, we've lost our |
| 445 // UserGestureToken, and need to create a new one to enter fullscreen. |
| 446 gestureIndicator = |
| 447 wrapUnique(new UserGestureIndicator(DocumentUserGestureToken::create( |
| 448 doc, UserGestureToken::Status::PossiblyExistingGesture))); |
| 449 } |
| 450 Fullscreen::requestFullscreen(*canvas, Fullscreen::UnprefixedRequest); |
| 451 |
| 452 // Check to see if the canvas is still the current fullscreen |
| 453 // element once every 5 seconds. |
| 454 m_fullscreenCheckTimer.startRepeating(5.0, BLINK_FROM_HERE); |
446 } | 455 } |
447 | 456 |
448 Document* doc = m_navigatorVR->document(); | |
449 if (doc) { | 457 if (doc) { |
450 Platform::current()->recordRapporURL("VR.WebVR.PresentSuccess", | 458 Platform::current()->recordRapporURL("VR.WebVR.PresentSuccess", |
451 WebURL(doc->url())); | 459 WebURL(doc->url())); |
452 } | 460 } |
453 | 461 |
454 m_isPresenting = true; | 462 m_isPresenting = true; |
455 ReportPresentationResult(PresentationResult::Success); | 463 ReportPresentationResult(PresentationResult::Success); |
456 | 464 |
457 updateLayerBounds(); | 465 updateLayerBounds(); |
458 | 466 |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 visitor->trace(m_capabilities); | 671 visitor->trace(m_capabilities); |
664 visitor->trace(m_stageParameters); | 672 visitor->trace(m_stageParameters); |
665 visitor->trace(m_eyeParametersLeft); | 673 visitor->trace(m_eyeParametersLeft); |
666 visitor->trace(m_eyeParametersRight); | 674 visitor->trace(m_eyeParametersRight); |
667 visitor->trace(m_layer); | 675 visitor->trace(m_layer); |
668 visitor->trace(m_renderingContext); | 676 visitor->trace(m_renderingContext); |
669 visitor->trace(m_scriptedAnimationController); | 677 visitor->trace(m_scriptedAnimationController); |
670 } | 678 } |
671 | 679 |
672 } // namespace blink | 680 } // namespace blink |
OLD | NEW |