Index: third_party/WebKit/Source/modules/vr/VRDisplay.cpp |
diff --git a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp |
index 11ab5b1492fcfed302b5e14326125fbd7c55e089..e9da95486e237707caff77dd1562175ccf5fdedc 100644 |
--- a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp |
+++ b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp |
@@ -261,7 +261,7 @@ ScriptPromise VRDisplay::requestPresent(ScriptState* scriptState, |
// If what we were given has an invalid source, need to exit fullscreen with |
// previous, valid source, so delay m_layer reassignment |
- if (!layers[0].source()) { |
+ if (layers[0].source().isNull()) { |
forceExitPresent(); |
DOMException* exception = |
DOMException::create(InvalidStateError, "Invalid layer source."); |
@@ -271,8 +271,15 @@ ScriptPromise VRDisplay::requestPresent(ScriptState* scriptState, |
} |
m_layer = layers[0]; |
- CanvasRenderingContext* renderingContext = |
- m_layer.source()->renderingContext(); |
+ CanvasRenderingContext* renderingContext; |
+ if (m_layer.source().isHTMLCanvasElement()) { |
+ renderingContext = |
+ m_layer.source().getAsHTMLCanvasElement()->renderingContext(); |
+ } else { |
+ DCHECK(m_layer.source().isOffscreenCanvas()); |
+ renderingContext = |
+ m_layer.source().getAsOffscreenCanvas()->renderingContext(); |
+ } |
if (!renderingContext || !renderingContext->is3d()) { |
forceExitPresent(); |
@@ -386,48 +393,65 @@ void VRDisplay::beginPresent() { |
PresentationResult::PresentationNotSupportedByDisplay); |
return; |
} else { |
- // TODO(klausw,crbug.com/655722): Need a proper VR compositor, but |
- // for the moment on mobile we'll just make the canvas fullscreen |
- // so that VrShell can pick it up through the standard (high |
- // latency) compositing path. |
- auto canvas = m_layer.source(); |
- auto inlineStyle = canvas->inlineStyle(); |
- if (inlineStyle) { |
- // THREE.js's VREffect sets explicit style.width/height on its rendering |
- // canvas based on the non-fullscreen window dimensions, and it keeps |
- // those unchanged when presenting. Unfortunately it appears that a |
- // fullscreened canvas just gets centered if it has explicitly set a |
- // size smaller than the fullscreen dimensions. Manually set size to |
- // 100% in this case and restore it when exiting fullscreen. This is a |
- // stopgap measure since THREE.js's usage appears legal according to the |
- // WebVR API spec. This will no longer be necessary once we can get rid |
- // of this fullscreen hack. |
- m_fullscreenOrigWidth = inlineStyle->getPropertyValue(CSSPropertyWidth); |
- if (!m_fullscreenOrigWidth.isNull()) { |
- canvas->setInlineStyleProperty(CSSPropertyWidth, "100%"); |
+ if (m_layer.source().isHTMLCanvasElement()) { |
+ HTMLCanvasElement* canvas = m_layer.source().getAsHTMLCanvasElement(); |
+ // TODO(klausw,crbug.com/655722): Need a proper VR compositor, but |
+ // for the moment on mobile we'll just make the canvas fullscreen |
+ // so that VrShell can pick it up through the standard (high |
+ // latency) compositing path. auto canvas = |
+ // m_layer.source().getAsHTMLCanvasElement(); |
+ auto inlineStyle = canvas->inlineStyle(); |
+ if (inlineStyle) { |
+ // THREE.js's VREffect sets explicit style.width/height on its rendering |
+ // canvas based on the non-fullscreen window dimensions, and it keeps |
+ // those unchanged when presenting. Unfortunately it appears that a |
+ // fullscreened canvas just gets centered if it has explicitly set a |
+ // size smaller than the fullscreen dimensions. Manually set size to |
+ // 100% in this case and restore it when exiting fullscreen. This is a |
+ // stopgap measure since THREE.js's usage appears legal according to the |
+ // WebVR API spec. This will no longer be necessary once we can get rid |
+ // of this fullscreen hack. |
+ m_fullscreenOrigWidth = inlineStyle->getPropertyValue(CSSPropertyWidth); |
+ if (!m_fullscreenOrigWidth.isNull()) { |
+ canvas->setInlineStyleProperty(CSSPropertyWidth, "100%"); |
+ } |
+ m_fullscreenOrigHeight = |
+ inlineStyle->getPropertyValue(CSSPropertyHeight); |
+ if (!m_fullscreenOrigHeight.isNull()) { |
+ canvas->setInlineStyleProperty(CSSPropertyHeight, "100%"); |
+ } |
+ } else { |
+ m_fullscreenOrigWidth = String(); |
+ m_fullscreenOrigHeight = String(); |
} |
- m_fullscreenOrigHeight = inlineStyle->getPropertyValue(CSSPropertyHeight); |
- if (!m_fullscreenOrigHeight.isNull()) { |
- canvas->setInlineStyleProperty(CSSPropertyHeight, "100%"); |
+ |
+ if (doc) { |
+ // Since the callback for requestPresent is asynchronous, we've lost our |
+ // UserGestureToken, and need to create a new one to enter fullscreen. |
+ gestureIndicator = WTF::wrapUnique( |
+ new UserGestureIndicator(DocumentUserGestureToken::create( |
+ doc, UserGestureToken::Status::PossiblyExistingGesture))); |
} |
- } else { |
- m_fullscreenOrigWidth = String(); |
- m_fullscreenOrigHeight = String(); |
- } |
+ Fullscreen::requestFullscreen(*canvas); |
- if (doc) { |
- // Since the callback for requestPresent is asynchronous, we've lost our |
- // UserGestureToken, and need to create a new one to enter fullscreen. |
- gestureIndicator = WTF::wrapUnique( |
- new UserGestureIndicator(DocumentUserGestureToken::create( |
- doc, UserGestureToken::Status::PossiblyExistingGesture))); |
+ // Check to see if the canvas is still the current fullscreen |
+ // element once every 2 seconds. |
+ m_fullscreenCheckTimer.startRepeating(2.0, BLINK_FROM_HERE); |
+ m_reenteredFullscreen = false; |
+ } else { |
+ DCHECK(m_layer.source().isOffscreenCanvas()); |
+ // TODO(junov, crbug.com/695497): Implement OffscreenCanvas presentation |
+ forceExitPresent(); |
+ DOMException* exception = DOMException::create( |
+ InvalidStateError, "OffscreenCanvas presentation not implemented."); |
+ while (!m_pendingPresentResolvers.isEmpty()) { |
+ ScriptPromiseResolver* resolver = m_pendingPresentResolvers.takeFirst(); |
+ resolver->reject(exception); |
+ } |
+ ReportPresentationResult( |
+ PresentationResult::PresentationNotSupportedByDisplay); |
+ return; |
} |
- Fullscreen::requestFullscreen(*canvas); |
- |
- // Check to see if the canvas is still the current fullscreen |
- // element once every 2 seconds. |
- m_fullscreenCheckTimer.startRepeating(2.0, BLINK_FROM_HERE); |
- m_reenteredFullscreen = false; |
} |
if (doc) { |
@@ -610,17 +634,22 @@ void VRDisplay::onDisconnected() { |
void VRDisplay::stopPresenting() { |
if (m_isPresenting) { |
if (!m_capabilities->hasExternalDisplay()) { |
- auto canvas = m_layer.source(); |
- Fullscreen::fullyExitFullscreen(canvas->document()); |
- m_fullscreenCheckTimer.stop(); |
- if (!m_fullscreenOrigWidth.isNull()) { |
- canvas->setInlineStyleProperty(CSSPropertyWidth, m_fullscreenOrigWidth); |
- m_fullscreenOrigWidth = String(); |
- } |
- if (!m_fullscreenOrigHeight.isNull()) { |
- canvas->setInlineStyleProperty(CSSPropertyWidth, |
- m_fullscreenOrigHeight); |
- m_fullscreenOrigHeight = String(); |
+ if (m_layer.source().isHTMLCanvasElement()) { |
+ auto canvas = m_layer.source().getAsHTMLCanvasElement(); |
+ Fullscreen::fullyExitFullscreen(canvas->document()); |
+ m_fullscreenCheckTimer.stop(); |
+ if (!m_fullscreenOrigWidth.isNull()) { |
+ canvas->setInlineStyleProperty(CSSPropertyWidth, |
+ m_fullscreenOrigWidth); |
+ m_fullscreenOrigWidth = String(); |
+ } |
+ if (!m_fullscreenOrigHeight.isNull()) { |
+ canvas->setInlineStyleProperty(CSSPropertyWidth, |
+ m_fullscreenOrigHeight); |
+ m_fullscreenOrigHeight = String(); |
+ } |
+ } else { |
+ // TODO(junov, crbug.com/695497): Implement for OffscreenCanvas |
} |
} else { |
// Can't get into this presentation mode, so nothing to do here. |
@@ -692,6 +721,7 @@ void VRDisplay::ConnectVSyncProvider() { |
} |
void VRDisplay::onFullscreenCheck(TimerBase*) { |
+ DCHECK(m_layer.source().isHTMLCanvasElement()); |
if (!m_isPresenting) { |
m_fullscreenCheckTimer.stop(); |
return; |
@@ -701,7 +731,8 @@ void VRDisplay::onFullscreenCheck(TimerBase*) { |
// depend on the Fullscreen API to fake VR presentation, so this will |
// become unnessecary. Until that point, though, this seems preferable to |
// adding a bunch of notification plumbing to Fullscreen. |
- if (!Fullscreen::isCurrentFullScreenElement(*m_layer.source())) { |
+ if (!Fullscreen::isCurrentFullScreenElement( |
+ *m_layer.source().getAsHTMLCanvasElement())) { |
// TODO(mthiesse): Due to asynchronous resizing, we might get kicked out of |
// fullscreen when changing display parameters upon entering WebVR. So one |
// time only, we reenter fullscreen after having left it; otherwise we exit |
@@ -715,7 +746,7 @@ void VRDisplay::onFullscreenCheck(TimerBase*) { |
return; |
} |
m_reenteredFullscreen = true; |
- auto canvas = m_layer.source(); |
+ auto canvas = m_layer.source().getAsHTMLCanvasElement(); |
Document* doc = this->document(); |
std::unique_ptr<UserGestureIndicator> gestureIndicator; |
if (doc) { |