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 cc8f1038aae5d967f3865cc8b9a1881194dcb3d9..10267f9e53965272bd0d75db16b405050e41d713 100644 |
--- a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp |
+++ b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp |
@@ -4,13 +4,14 @@ |
#include "modules/vr/VRDisplay.h" |
+#include "cc/resources/texture_mailbox.h" |
#include "core/css/StylePropertySet.h" |
#include "core/dom/DOMException.h" |
#include "core/dom/DocumentUserGestureToken.h" |
#include "core/dom/FrameRequestCallback.h" |
-#include "core/dom/Fullscreen.h" |
#include "core/dom/ScriptedAnimationController.h" |
#include "core/dom/TaskRunnerHelper.h" |
+#include "core/frame/ImageBitmap.h" |
#include "core/frame/UseCounter.h" |
#include "core/inspector/ConsoleMessage.h" |
#include "core/loader/DocumentLoader.h" |
@@ -33,13 +34,17 @@ |
#include <array> |
+#include "core/frame/FrameView.h" |
+ |
namespace blink { |
namespace { |
+#if 0 |
// Magic numbers used to mark valid pose index values encoded in frame |
// data. Must match the magic numbers used in vr_shell.cc. |
static constexpr std::array<uint8_t, 2> kWebVrPosePixelMagicNumbers{{42, 142}}; |
+#endif |
VREye stringToVREye(const String& whichEye) { |
if (whichEye == "left") |
@@ -59,11 +64,6 @@ VRDisplay::VRDisplay(NavigatorVR* navigatorVR, |
m_capabilities(new VRDisplayCapabilities()), |
m_eyeParametersLeft(new VREyeParameters()), |
m_eyeParametersRight(new VREyeParameters()), |
- m_fullscreenCheckTimer( |
- TaskRunnerHelper::get(TaskType::UnspecedTimer, |
- navigatorVR->document()->frame()), |
- this, |
- &VRDisplay::onFullscreenCheck), |
m_display(std::move(display)), |
m_displayClientBinding(this, std::move(request)) {} |
@@ -158,6 +158,7 @@ int VRDisplay::requestAnimationFrame(FrameRequestCallback* callback) { |
Document* doc = this->document(); |
if (!doc) |
return 0; |
+ VLOG(1) << __FUNCTION__ << ";;;"; |
m_pendingRaf = true; |
if (!m_vrVSyncProvider.is_bound()) { |
ConnectVSyncProvider(); |
@@ -239,17 +240,6 @@ ScriptPromise VRDisplay::requestPresent(ScriptState* scriptState, |
return promise; |
} |
- // TODO(mthiesse): Remove fullscreen requirement for presentation. See |
- // crbug.com/687369 |
- Document* doc = this->document(); |
- if (!doc || !Fullscreen::fullscreenEnabled(*doc)) { |
- DOMException* exception = |
- DOMException::create(InvalidStateError, "Fullscreen is not enabled."); |
- resolver->reject(exception); |
- ReportPresentationResult(PresentationResult::FullscreenNotEnabled); |
- return promise; |
- } |
- |
// A valid number of layers must be provided in order to present. |
if (layers.size() == 0 || layers.size() > m_capabilities->maxLayers()) { |
forceExitPresent(); |
@@ -395,50 +385,13 @@ void VRDisplay::beginPresent() { |
return; |
} else { |
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(); |
- } |
- |
- 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))); |
- } |
- 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; |
+ // Stop unneeded compositor updates. We do so by hiding the view. We can't |
+ // hide the page, doing so causes an assertion failure (!m_isHidden) in |
+ // DrawingBuffer::prepareTextureMailboxInternal(). Do this only when we're |
+ // actually presenting (m_isPresenting is true), see corresponding show() |
+ // in forceExitPresent(). Otherwise the view may remain hidden for failing |
+ // DON flow. |
+ m_navigatorVR->document()->view()->hide(); |
} else { |
DCHECK(m_layer.source().isOffscreenCanvas()); |
// TODO(junov, crbug.com/695497): Implement OffscreenCanvas presentation |
@@ -567,6 +520,7 @@ void VRDisplay::submitFrame() { |
return; |
} |
+#if 0 |
// Write the frame number for the pose used into a bottom left pixel block. |
// It is read by chrome/browser/android/vr_shell/vr_shell.cc to associate |
// the correct corresponding pose for submission. |
@@ -597,7 +551,32 @@ void VRDisplay::submitFrame() { |
m_renderingContext->restoreScissorBox(); |
m_renderingContext->restoreColorMask(); |
m_renderingContext->restoreClearColor(); |
+#endif |
+ //auto image = m_renderingContext->getImage(PreferAcceleration, SnapshotReasonTransferToImageBitmap); |
+ auto elem = m_layer.source(); |
+ ImageBitmap* image; |
+ if (elem.isHTMLCanvasElement()) { |
+ image = ImageBitmap::create(elem.getAsHTMLCanvasElement(), |
+ WTF::nullopt, ImageBitmapOptions()); |
+ } else { |
+ image = ImageBitmap::create(elem.getAsOffscreenCanvas(), |
+ WTF::nullopt, ImageBitmapOptions()); |
+ } |
+ StaticBitmapImage* bitmap = image->bitmapImage(); |
+ bitmap->ensureMailbox(); |
+ VLOG(1) << __FUNCTION__ << ";;; got bitmap, hasMailbox=" << bitmap->hasMailbox(); |
+ auto mailbox = bitmap->mailbox(); |
+ m_contextGL->WaitSyncTokenCHROMIUM(bitmap->syncToken().GetData()); |
+ VLOG(1) << __FUNCTION__ << ";;; got mailbox, name=" << (int)mailbox.name[0] << "," << (int)mailbox.name[1] << "..."; |
+ |
+ m_framePose->mailbox = gpu::mojom::blink::Mailbox::New(); |
+ WTF::Vector<int8_t> tmpname(GL_MAILBOX_SIZE_CHROMIUM); |
+ memcpy(&tmpname[0], &mailbox.name[0], GL_MAILBOX_SIZE_CHROMIUM); |
+ m_framePose->mailbox->name = std::move(tmpname); |
+ |
+ m_framePose->frameId = m_vrFrameId; |
+ VLOG(1) << __FUNCTION__ << ";;; SubmitFrame frame=" << m_vrFrameId; |
m_display->SubmitFrame(m_framePose.Clone()); |
} |
@@ -636,19 +615,7 @@ void VRDisplay::stopPresenting() { |
if (m_isPresenting) { |
if (!m_capabilities->hasExternalDisplay()) { |
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(); |
- } |
+ m_navigatorVR->document()->view()->show(); |
} else { |
// TODO(junov, crbug.com/695497): Implement for OffscreenCanvas |
} |
@@ -723,44 +690,6 @@ void VRDisplay::ConnectVSyncProvider() { |
} |
} |
-void VRDisplay::onFullscreenCheck(TimerBase*) { |
- DCHECK(m_layer.source().isHTMLCanvasElement()); |
- if (!m_isPresenting) { |
- m_fullscreenCheckTimer.stop(); |
- return; |
- } |
- // TODO: This is a temporary measure to track if fullscreen mode has been |
- // exited by the UA. If so we need to end VR presentation. Soon we won't |
- // 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().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 |
- // presentation. |
- if (m_reenteredFullscreen) { |
- m_isPresenting = false; |
- OnPresentChange(); |
- m_fullscreenCheckTimer.stop(); |
- if (m_display) |
- m_display->ExitPresent(); |
- return; |
- } |
- m_reenteredFullscreen = true; |
- auto canvas = m_layer.source().getAsHTMLCanvasElement(); |
- Document* doc = this->document(); |
- std::unique_ptr<UserGestureIndicator> gestureIndicator; |
- if (doc) { |
- gestureIndicator = WTF::wrapUnique( |
- new UserGestureIndicator(DocumentUserGestureToken::create( |
- doc, UserGestureToken::Status::PossiblyExistingGesture))); |
- } |
- Fullscreen::requestFullscreen(*canvas); |
- } |
-} |
- |
ScriptedAnimationController& VRDisplay::ensureScriptedAnimationController( |
Document* doc) { |
if (!m_scriptedAnimationController) |