Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: third_party/WebKit/Source/modules/vr/VRDisplay.cpp

Issue 2711513006: Add OffscreenCanvas to VRSource (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | third_party/WebKit/Source/modules/vr/VRLayer.idl » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 forceExitPresent(); 254 forceExitPresent();
255 DOMException* exception = 255 DOMException* exception =
256 DOMException::create(InvalidStateError, "Invalid number of layers."); 256 DOMException::create(InvalidStateError, "Invalid number of layers.");
257 resolver->reject(exception); 257 resolver->reject(exception);
258 ReportPresentationResult(PresentationResult::InvalidNumberOfLayers); 258 ReportPresentationResult(PresentationResult::InvalidNumberOfLayers);
259 return promise; 259 return promise;
260 } 260 }
261 261
262 // If what we were given has an invalid source, need to exit fullscreen with 262 // If what we were given has an invalid source, need to exit fullscreen with
263 // previous, valid source, so delay m_layer reassignment 263 // previous, valid source, so delay m_layer reassignment
264 if (!layers[0].source()) { 264 if (layers[0].source().isNull()) {
265 forceExitPresent(); 265 forceExitPresent();
266 DOMException* exception = 266 DOMException* exception =
267 DOMException::create(InvalidStateError, "Invalid layer source."); 267 DOMException::create(InvalidStateError, "Invalid layer source.");
268 resolver->reject(exception); 268 resolver->reject(exception);
269 ReportPresentationResult(PresentationResult::InvalidLayerSource); 269 ReportPresentationResult(PresentationResult::InvalidLayerSource);
270 return promise; 270 return promise;
271 } 271 }
272 m_layer = layers[0]; 272 m_layer = layers[0];
273 273
274 CanvasRenderingContext* renderingContext = 274 CanvasRenderingContext* renderingContext;
275 m_layer.source()->renderingContext(); 275 if (m_layer.source().isHTMLCanvasElement()) {
276 renderingContext =
277 m_layer.source().getAsHTMLCanvasElement()->renderingContext();
278 } else {
279 DCHECK(m_layer.source().isOffscreenCanvas());
280 renderingContext =
281 m_layer.source().getAsOffscreenCanvas()->renderingContext();
282 }
276 283
277 if (!renderingContext || !renderingContext->is3d()) { 284 if (!renderingContext || !renderingContext->is3d()) {
278 forceExitPresent(); 285 forceExitPresent();
279 DOMException* exception = DOMException::create( 286 DOMException* exception = DOMException::create(
280 InvalidStateError, "Layer source must have a WebGLRenderingContext"); 287 InvalidStateError, "Layer source must have a WebGLRenderingContext");
281 resolver->reject(exception); 288 resolver->reject(exception);
282 ReportPresentationResult( 289 ReportPresentationResult(
283 PresentationResult::LayerSourceMissingWebGLContext); 290 PresentationResult::LayerSourceMissingWebGLContext);
284 return promise; 291 return promise;
285 } 292 }
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 InvalidStateError, 386 InvalidStateError,
380 "VR Presentation not implemented for this VRDisplay."); 387 "VR Presentation not implemented for this VRDisplay.");
381 while (!m_pendingPresentResolvers.isEmpty()) { 388 while (!m_pendingPresentResolvers.isEmpty()) {
382 ScriptPromiseResolver* resolver = m_pendingPresentResolvers.takeFirst(); 389 ScriptPromiseResolver* resolver = m_pendingPresentResolvers.takeFirst();
383 resolver->reject(exception); 390 resolver->reject(exception);
384 } 391 }
385 ReportPresentationResult( 392 ReportPresentationResult(
386 PresentationResult::PresentationNotSupportedByDisplay); 393 PresentationResult::PresentationNotSupportedByDisplay);
387 return; 394 return;
388 } else { 395 } else {
389 // TODO(klausw,crbug.com/655722): Need a proper VR compositor, but 396 if (m_layer.source().isHTMLCanvasElement()) {
390 // for the moment on mobile we'll just make the canvas fullscreen 397 HTMLCanvasElement* canvas = m_layer.source().getAsHTMLCanvasElement();
391 // so that VrShell can pick it up through the standard (high 398 // TODO(klausw,crbug.com/655722): Need a proper VR compositor, but
392 // latency) compositing path. 399 // for the moment on mobile we'll just make the canvas fullscreen
393 auto canvas = m_layer.source(); 400 // so that VrShell can pick it up through the standard (high
394 auto inlineStyle = canvas->inlineStyle(); 401 // latency) compositing path. auto canvas =
395 if (inlineStyle) { 402 // m_layer.source().getAsHTMLCanvasElement();
396 // THREE.js's VREffect sets explicit style.width/height on its rendering 403 auto inlineStyle = canvas->inlineStyle();
397 // canvas based on the non-fullscreen window dimensions, and it keeps 404 if (inlineStyle) {
398 // those unchanged when presenting. Unfortunately it appears that a 405 // THREE.js's VREffect sets explicit style.width/height on its rendering
399 // fullscreened canvas just gets centered if it has explicitly set a 406 // canvas based on the non-fullscreen window dimensions, and it keeps
400 // size smaller than the fullscreen dimensions. Manually set size to 407 // those unchanged when presenting. Unfortunately it appears that a
401 // 100% in this case and restore it when exiting fullscreen. This is a 408 // fullscreened canvas just gets centered if it has explicitly set a
402 // stopgap measure since THREE.js's usage appears legal according to the 409 // size smaller than the fullscreen dimensions. Manually set size to
403 // WebVR API spec. This will no longer be necessary once we can get rid 410 // 100% in this case and restore it when exiting fullscreen. This is a
404 // of this fullscreen hack. 411 // stopgap measure since THREE.js's usage appears legal according to the
405 m_fullscreenOrigWidth = inlineStyle->getPropertyValue(CSSPropertyWidth); 412 // WebVR API spec. This will no longer be necessary once we can get rid
406 if (!m_fullscreenOrigWidth.isNull()) { 413 // of this fullscreen hack.
407 canvas->setInlineStyleProperty(CSSPropertyWidth, "100%"); 414 m_fullscreenOrigWidth = inlineStyle->getPropertyValue(CSSPropertyWidth);
415 if (!m_fullscreenOrigWidth.isNull()) {
416 canvas->setInlineStyleProperty(CSSPropertyWidth, "100%");
417 }
418 m_fullscreenOrigHeight =
419 inlineStyle->getPropertyValue(CSSPropertyHeight);
420 if (!m_fullscreenOrigHeight.isNull()) {
421 canvas->setInlineStyleProperty(CSSPropertyHeight, "100%");
422 }
423 } else {
424 m_fullscreenOrigWidth = String();
425 m_fullscreenOrigHeight = String();
408 } 426 }
409 m_fullscreenOrigHeight = inlineStyle->getPropertyValue(CSSPropertyHeight); 427
410 if (!m_fullscreenOrigHeight.isNull()) { 428 if (doc) {
411 canvas->setInlineStyleProperty(CSSPropertyHeight, "100%"); 429 // Since the callback for requestPresent is asynchronous, we've lost our
430 // UserGestureToken, and need to create a new one to enter fullscreen.
431 gestureIndicator = WTF::wrapUnique(
432 new UserGestureIndicator(DocumentUserGestureToken::create(
433 doc, UserGestureToken::Status::PossiblyExistingGesture)));
412 } 434 }
435 Fullscreen::requestFullscreen(*canvas);
436
437 // Check to see if the canvas is still the current fullscreen
438 // element once every 2 seconds.
439 m_fullscreenCheckTimer.startRepeating(2.0, BLINK_FROM_HERE);
440 m_reenteredFullscreen = false;
413 } else { 441 } else {
414 m_fullscreenOrigWidth = String(); 442 DCHECK(m_layer.source().isOffscreenCanvas());
415 m_fullscreenOrigHeight = String(); 443 // TODO(junov, crbug.com/695497): Implement OffscreenCanvas presentation
444 forceExitPresent();
445 DOMException* exception = DOMException::create(
446 InvalidStateError, "OffscreenCanvas presentation not implemented.");
447 while (!m_pendingPresentResolvers.isEmpty()) {
448 ScriptPromiseResolver* resolver = m_pendingPresentResolvers.takeFirst();
449 resolver->reject(exception);
450 }
451 ReportPresentationResult(
452 PresentationResult::PresentationNotSupportedByDisplay);
453 return;
416 } 454 }
417
418 if (doc) {
419 // Since the callback for requestPresent is asynchronous, we've lost our
420 // UserGestureToken, and need to create a new one to enter fullscreen.
421 gestureIndicator = WTF::wrapUnique(
422 new UserGestureIndicator(DocumentUserGestureToken::create(
423 doc, UserGestureToken::Status::PossiblyExistingGesture)));
424 }
425 Fullscreen::requestFullscreen(*canvas);
426
427 // Check to see if the canvas is still the current fullscreen
428 // element once every 2 seconds.
429 m_fullscreenCheckTimer.startRepeating(2.0, BLINK_FROM_HERE);
430 m_reenteredFullscreen = false;
431 } 455 }
432 456
433 if (doc) { 457 if (doc) {
434 Platform::current()->recordRapporURL("VR.WebVR.PresentSuccess", 458 Platform::current()->recordRapporURL("VR.WebVR.PresentSuccess",
435 WebURL(doc->url())); 459 WebURL(doc->url()));
436 } 460 }
437 461
438 m_isPresenting = true; 462 m_isPresenting = true;
439 ReportPresentationResult(PresentationResult::Success); 463 ReportPresentationResult(PresentationResult::Success);
440 464
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 } 627 }
604 628
605 void VRDisplay::onDisconnected() { 629 void VRDisplay::onDisconnected() {
606 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create( 630 m_navigatorVR->enqueueVREvent(VRDisplayEvent::create(
607 EventTypeNames::vrdisplaydisconnect, true, false, this, "disconnect")); 631 EventTypeNames::vrdisplaydisconnect, true, false, this, "disconnect"));
608 } 632 }
609 633
610 void VRDisplay::stopPresenting() { 634 void VRDisplay::stopPresenting() {
611 if (m_isPresenting) { 635 if (m_isPresenting) {
612 if (!m_capabilities->hasExternalDisplay()) { 636 if (!m_capabilities->hasExternalDisplay()) {
613 auto canvas = m_layer.source(); 637 if (m_layer.source().isHTMLCanvasElement()) {
614 Fullscreen::fullyExitFullscreen(canvas->document()); 638 auto canvas = m_layer.source().getAsHTMLCanvasElement();
615 m_fullscreenCheckTimer.stop(); 639 Fullscreen::fullyExitFullscreen(canvas->document());
616 if (!m_fullscreenOrigWidth.isNull()) { 640 m_fullscreenCheckTimer.stop();
617 canvas->setInlineStyleProperty(CSSPropertyWidth, m_fullscreenOrigWidth); 641 if (!m_fullscreenOrigWidth.isNull()) {
618 m_fullscreenOrigWidth = String(); 642 canvas->setInlineStyleProperty(CSSPropertyWidth,
619 } 643 m_fullscreenOrigWidth);
620 if (!m_fullscreenOrigHeight.isNull()) { 644 m_fullscreenOrigWidth = String();
621 canvas->setInlineStyleProperty(CSSPropertyWidth, 645 }
622 m_fullscreenOrigHeight); 646 if (!m_fullscreenOrigHeight.isNull()) {
623 m_fullscreenOrigHeight = String(); 647 canvas->setInlineStyleProperty(CSSPropertyWidth,
648 m_fullscreenOrigHeight);
649 m_fullscreenOrigHeight = String();
650 }
651 } else {
652 // TODO(junov, crbug.com/695497): Implement for OffscreenCanvas
624 } 653 }
625 } else { 654 } else {
626 // Can't get into this presentation mode, so nothing to do here. 655 // Can't get into this presentation mode, so nothing to do here.
627 } 656 }
628 m_isPresenting = false; 657 m_isPresenting = false;
629 OnPresentChange(); 658 OnPresentChange();
630 } 659 }
631 660
632 m_renderingContext = nullptr; 661 m_renderingContext = nullptr;
633 m_contextGL = nullptr; 662 m_contextGL = nullptr;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
685 if (!m_navigatorVR->isFocused()) 714 if (!m_navigatorVR->isFocused())
686 return; 715 return;
687 m_display->GetVRVSyncProvider(mojo::MakeRequest(&m_vrVSyncProvider)); 716 m_display->GetVRVSyncProvider(mojo::MakeRequest(&m_vrVSyncProvider));
688 if (m_pendingRaf && !m_displayBlurred) { 717 if (m_pendingRaf && !m_displayBlurred) {
689 m_vrVSyncProvider->GetVSync(convertToBaseCallback( 718 m_vrVSyncProvider->GetVSync(convertToBaseCallback(
690 WTF::bind(&VRDisplay::OnVSync, wrapWeakPersistent(this)))); 719 WTF::bind(&VRDisplay::OnVSync, wrapWeakPersistent(this))));
691 } 720 }
692 } 721 }
693 722
694 void VRDisplay::onFullscreenCheck(TimerBase*) { 723 void VRDisplay::onFullscreenCheck(TimerBase*) {
724 DCHECK(m_layer.source().isHTMLCanvasElement());
695 if (!m_isPresenting) { 725 if (!m_isPresenting) {
696 m_fullscreenCheckTimer.stop(); 726 m_fullscreenCheckTimer.stop();
697 return; 727 return;
698 } 728 }
699 // TODO: This is a temporary measure to track if fullscreen mode has been 729 // TODO: This is a temporary measure to track if fullscreen mode has been
700 // exited by the UA. If so we need to end VR presentation. Soon we won't 730 // exited by the UA. If so we need to end VR presentation. Soon we won't
701 // depend on the Fullscreen API to fake VR presentation, so this will 731 // depend on the Fullscreen API to fake VR presentation, so this will
702 // become unnessecary. Until that point, though, this seems preferable to 732 // become unnessecary. Until that point, though, this seems preferable to
703 // adding a bunch of notification plumbing to Fullscreen. 733 // adding a bunch of notification plumbing to Fullscreen.
704 if (!Fullscreen::isCurrentFullScreenElement(*m_layer.source())) { 734 if (!Fullscreen::isCurrentFullScreenElement(
735 *m_layer.source().getAsHTMLCanvasElement())) {
705 // TODO(mthiesse): Due to asynchronous resizing, we might get kicked out of 736 // TODO(mthiesse): Due to asynchronous resizing, we might get kicked out of
706 // fullscreen when changing display parameters upon entering WebVR. So one 737 // fullscreen when changing display parameters upon entering WebVR. So one
707 // time only, we reenter fullscreen after having left it; otherwise we exit 738 // time only, we reenter fullscreen after having left it; otherwise we exit
708 // presentation. 739 // presentation.
709 if (m_reenteredFullscreen) { 740 if (m_reenteredFullscreen) {
710 m_isPresenting = false; 741 m_isPresenting = false;
711 OnPresentChange(); 742 OnPresentChange();
712 m_fullscreenCheckTimer.stop(); 743 m_fullscreenCheckTimer.stop();
713 if (m_display) 744 if (m_display)
714 m_display->ExitPresent(); 745 m_display->ExitPresent();
715 return; 746 return;
716 } 747 }
717 m_reenteredFullscreen = true; 748 m_reenteredFullscreen = true;
718 auto canvas = m_layer.source(); 749 auto canvas = m_layer.source().getAsHTMLCanvasElement();
719 Document* doc = this->document(); 750 Document* doc = this->document();
720 std::unique_ptr<UserGestureIndicator> gestureIndicator; 751 std::unique_ptr<UserGestureIndicator> gestureIndicator;
721 if (doc) { 752 if (doc) {
722 gestureIndicator = WTF::wrapUnique( 753 gestureIndicator = WTF::wrapUnique(
723 new UserGestureIndicator(DocumentUserGestureToken::create( 754 new UserGestureIndicator(DocumentUserGestureToken::create(
724 doc, UserGestureToken::Status::PossiblyExistingGesture))); 755 doc, UserGestureToken::Status::PossiblyExistingGesture)));
725 } 756 }
726 Fullscreen::requestFullscreen(*canvas); 757 Fullscreen::requestFullscreen(*canvas);
727 } 758 }
728 } 759 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 visitor->trace(m_stageParameters); 804 visitor->trace(m_stageParameters);
774 visitor->trace(m_eyeParametersLeft); 805 visitor->trace(m_eyeParametersLeft);
775 visitor->trace(m_eyeParametersRight); 806 visitor->trace(m_eyeParametersRight);
776 visitor->trace(m_layer); 807 visitor->trace(m_layer);
777 visitor->trace(m_renderingContext); 808 visitor->trace(m_renderingContext);
778 visitor->trace(m_scriptedAnimationController); 809 visitor->trace(m_scriptedAnimationController);
779 visitor->trace(m_pendingPresentResolvers); 810 visitor->trace(m_pendingPresentResolvers);
780 } 811 }
781 812
782 } // namespace blink 813 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/Source/modules/vr/VRLayer.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698