Chromium Code Reviews| 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 88ae98b7eea2d69815d12cd4d3b301cc5cac4c43..5e511c773e7870431647c5ac4cc1405a9973baf1 100644 |
| --- a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp |
| +++ b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp |
| @@ -174,73 +174,46 @@ ScriptPromise VRDisplay::requestPresent(ScriptState* scriptState, const HeapVect |
| // A valid number of layers must be provided in order to present. |
| if (layers.size() == 0 || layers.size() > m_capabilities->maxLayers()) { |
| + forceExitPresent(); |
| DOMException* exception = DOMException::create(InvalidStateError, "Invalid number of layers."); |
| - if (m_isPresenting) { |
| - exitPresent(scriptState); |
| - } |
| resolver->reject(exception); |
| return promise; |
| } |
| m_layer = layers[0]; |
| - if (m_layer.source()) { |
| - if (!m_capabilities->hasExternalDisplay()) { |
| - // TODO: 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. |
| - Fullscreen::requestFullscreen(*m_layer.source(), Fullscreen::UnprefixedRequest); |
| - |
| - m_isPresenting = true; |
| - |
| - resolver->resolve(); |
| - |
| - m_navigatorVR->fireVRDisplayPresentChange(this); |
| - |
| - // Check to see if the canvas is still the current fullscreen |
| - // element once per second. |
| - m_fullscreenCheckTimer.startRepeating(1.0, BLINK_FROM_HERE); |
| - |
| - controller()->requestPresent(m_displayId); |
| - } else { |
| - DOMException* exception = DOMException::create(InvalidStateError, "VR Presentation not implemented for this VRDisplay."); |
| - resolver->reject(exception); |
| - } |
| + if (!m_layer.source()) { |
| + forceExitPresent(); |
| + DOMException* exception = DOMException::create(InvalidStateError, "Invalid layer source."); |
| + resolver->reject(exception); |
| + return promise; |
| + } |
| - // Set up the texture bounds for the provided layer |
| - device::blink::VRLayerBoundsPtr leftBounds = device::blink::VRLayerBounds::New(); |
| - device::blink::VRLayerBoundsPtr rightBounds = device::blink::VRLayerBounds::New(); |
| + CanvasRenderingContext* renderingContext = m_layer.source()->renderingContext(); |
| - if (m_layer.hasLeftBounds()) { |
| - leftBounds->left = m_layer.leftBounds()[0]; |
| - leftBounds->top = m_layer.leftBounds()[1]; |
| - leftBounds->width = m_layer.leftBounds()[2]; |
| - leftBounds->height = m_layer.leftBounds()[3]; |
| - } else { |
| - // Left eye defaults |
| - leftBounds->left = 0.0f; |
| - leftBounds->top = 0.0f; |
| - leftBounds->width = 0.5f; |
| - leftBounds->height = 1.0f; |
| - } |
| + if (!renderingContext || !renderingContext->is3d()) { |
| + forceExitPresent(); |
| + DOMException* exception = DOMException::create(InvalidStateError, "Layer source must have a WebGLRenderingContext"); |
| + resolver->reject(exception); |
| + return promise; |
| + } |
| - if (m_layer.hasRightBounds()) { |
| - rightBounds->left = m_layer.rightBounds()[0]; |
| - rightBounds->top = m_layer.rightBounds()[1]; |
| - rightBounds->width = m_layer.rightBounds()[2]; |
| - rightBounds->height = m_layer.rightBounds()[3]; |
| - } else { |
| - // Right eye defaults |
| - rightBounds->left = 0.5f; |
| - rightBounds->top = 0.0f; |
| - rightBounds->width = 0.5f; |
| - rightBounds->height = 1.0f; |
| - } |
| + if (!m_capabilities->hasExternalDisplay()) { |
| + // TODO: 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. |
| + Fullscreen::requestFullscreen(*m_layer.source(), Fullscreen::UnprefixedRequest); |
| + |
| + // Check to see if the canvas is still the current fullscreen |
| + // element once per second. |
| + m_fullscreenCheckTimer.startRepeating(1.0, BLINK_FROM_HERE); |
|
mthiesse
2016/09/13 18:46:15
ew. I know this is already landed, so don't let my
bajones
2016/09/13 19:42:57
NO! It's not anywhere close to the best way to do
|
| + } |
| - controller()->updateLayerBounds(m_displayId, std::move(leftBounds), std::move(rightBounds)); |
| + if (firstPresent) { |
| + controller()->requestPresent(resolver, m_displayId); |
| } else { |
| - DOMException* exception = DOMException::create(InvalidStateError, "Invalid layer source."); |
| - resolver->reject(exception); |
| + updateLayerBounds(); |
| + resolver->resolve(); |
| } |
| return promise; |
| @@ -258,22 +231,80 @@ ScriptPromise VRDisplay::exitPresent(ScriptState* scriptState) |
| return promise; |
| } |
| - if (!m_capabilities->hasExternalDisplay()) { |
| - Fullscreen::fullyExitFullscreen(m_layer.source()->document()); |
| - m_fullscreenCheckTimer.stop(); |
| - controller()->exitPresent(m_displayId); |
| - } else { |
| - // Can't get into this presentation mode, so nothing to do here. |
| + controller()->exitPresent(m_displayId); |
| + |
| + resolver->resolve(); |
| + |
| + forceExitPresent(); |
| + |
| + return promise; |
| +} |
| + |
| +void VRDisplay::beginPresent(ScriptPromiseResolver* resolver) |
| +{ |
| + if (m_capabilities->hasExternalDisplay()) { |
| + forceExitPresent(); |
| + DOMException* exception = DOMException::create(InvalidStateError, "VR Presentation not implemented for this VRDisplay."); |
| + resolver->reject(exception); |
| + return; |
| } |
| - m_isPresenting = false; |
| + m_isPresenting = true; |
| - // TODO: Resolve when exit is confirmed |
| resolver->resolve(); |
| - |
| m_navigatorVR->fireVRDisplayPresentChange(this); |
| - return promise; |
| + updateLayerBounds(); |
|
mthiesse
2016/09/13 18:46:15
This feels like it should go before the PresentCha
bajones
2016/09/13 19:42:57
Done.
|
| +} |
| + |
| +void VRDisplay::forceExitPresent() |
| +{ |
| + if (m_isPresenting) { |
| + if (!m_capabilities->hasExternalDisplay()) { |
| + Fullscreen::fullyExitFullscreen(m_layer.source()->document()); |
| + m_fullscreenCheckTimer.stop(); |
| + } else { |
| + // Can't get into this presentation mode, so nothing to do here. |
| + } |
| + m_navigatorVR->fireVRDisplayPresentChange(this); |
| + } |
| + |
| + m_isPresenting = false; |
| +} |
| + |
| +void VRDisplay::updateLayerBounds() |
| +{ |
| + // Set up the texture bounds for the provided layer |
| + device::blink::VRLayerBoundsPtr leftBounds = device::blink::VRLayerBounds::New(); |
| + device::blink::VRLayerBoundsPtr rightBounds = device::blink::VRLayerBounds::New(); |
| + |
| + if (m_layer.hasLeftBounds()) { |
| + leftBounds->left = m_layer.leftBounds()[0]; |
| + leftBounds->top = m_layer.leftBounds()[1]; |
| + leftBounds->width = m_layer.leftBounds()[2]; |
| + leftBounds->height = m_layer.leftBounds()[3]; |
| + } else { |
| + // Left eye defaults |
| + leftBounds->left = 0.0f; |
| + leftBounds->top = 0.0f; |
| + leftBounds->width = 0.5f; |
| + leftBounds->height = 1.0f; |
| + } |
| + |
| + if (m_layer.hasRightBounds()) { |
| + rightBounds->left = m_layer.rightBounds()[0]; |
| + rightBounds->top = m_layer.rightBounds()[1]; |
| + rightBounds->width = m_layer.rightBounds()[2]; |
| + rightBounds->height = m_layer.rightBounds()[3]; |
| + } else { |
| + // Right eye defaults |
| + rightBounds->left = 0.5f; |
| + rightBounds->top = 0.0f; |
| + rightBounds->width = 0.5f; |
| + rightBounds->height = 1.0f; |
| + } |
| + |
| + controller()->updateLayerBounds(m_displayId, std::move(leftBounds), std::move(rightBounds)); |
| } |
| HeapVector<VRLayer> VRDisplay::getLayers() |
| @@ -289,7 +320,7 @@ HeapVector<VRLayer> VRDisplay::getLayers() |
| void VRDisplay::submitFrame() |
| { |
| - controller()->submitFrame(m_displayId); |
| + controller()->submitFrame(m_displayId, m_framePose.Clone()); |
| m_canUpdateFramePose = true; |
| } |