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

Unified Diff: third_party/WebKit/Source/modules/vr/VRDisplay.cpp

Issue 2729523002: Re-land^2 WebVR compositor bypass via BrowserMain context + mailbox (Closed)
Patch Set: Created 3 years, 10 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 side-by-side diff with in-line comments
Download patch
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)

Powered by Google App Engine
This is Rietveld 408576698