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 b7c149764abad85e4d1c99449b0fc3429db8e67b..e39fce2330b64dbca57992deddb339bd7d81d04f 100644 |
| --- a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp |
| +++ b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp |
| @@ -5,7 +5,9 @@ |
| #include "modules/vr/VRDisplay.h" |
| #include "core/dom/DOMException.h" |
| +#include "core/dom/FrameRequestCallback.h" |
| #include "core/dom/Fullscreen.h" |
| +#include "core/dom/ScriptedAnimationController.h" |
| #include "core/frame/UseCounter.h" |
| #include "core/inspector/ConsoleMessage.h" |
| #include "gpu/command_buffer/client/gles2_interface.h" |
| @@ -34,6 +36,24 @@ VREye stringToVREye(const String& whichEye) { |
| return VREyeNone; |
| } |
| +class VRDisplayFrameRequestCallback : public FrameRequestCallback { |
| + public: |
| + VRDisplayFrameRequestCallback(VRDisplay* vrDisplay) |
| + : m_vrDisplay(vrDisplay) {} |
| + ~VRDisplayFrameRequestCallback() override {} |
| + void handleEvent(double highResTimeMs) override { |
| + m_vrDisplay->serviceScriptedAnimations(highResTimeMs); |
| + } |
| + |
| + DEFINE_INLINE_VIRTUAL_TRACE() { |
| + visitor->trace(m_vrDisplay); |
| + |
| + FrameRequestCallback::trace(visitor); |
| + } |
| + |
| + Member<VRDisplay> m_vrDisplay; |
| +}; |
| + |
| } // namespace |
| VRDisplay::VRDisplay(NavigatorVR* navigatorVR) |
| @@ -47,7 +67,9 @@ VRDisplay::VRDisplay(NavigatorVR* navigatorVR) |
| m_eyeParametersRight(new VREyeParameters()), |
| m_depthNear(0.01), |
| m_depthFar(10000.0), |
| - m_fullscreenCheckTimer(this, &VRDisplay::onFullscreenCheck) {} |
| + m_fullscreenCheckTimer(this, &VRDisplay::onFullscreenCheck), |
| + m_animationCallbackRequested(false), |
| + m_inAnimationFrame(false) {} |
| VRDisplay::~VRDisplay() {} |
| @@ -132,16 +154,33 @@ VREyeParameters* VRDisplay::getEyeParameters(const String& whichEye) { |
| } |
| int VRDisplay::requestAnimationFrame(FrameRequestCallback* callback) { |
| - // TODO: Use HMD-specific rAF when an external display is present. |
| + Document* doc = m_navigatorVR->document(); |
| + if (!doc) |
| + return 0; |
| + |
| + if (!m_animationCallbackRequested) { |
| + doc->requestAnimationFrame(new VRDisplayFrameRequestCallback(this)); |
| + m_animationCallbackRequested = true; |
| + } |
| + |
| callback->m_useLegacyTimeBase = false; |
| - if (Document* doc = m_navigatorVR->document()) |
| - return doc->requestAnimationFrame(callback); |
| - return 0; |
| + return ensureScriptedAnimationController(doc).registerCallback(callback); |
|
Sami
2016/10/24 10:12:23
Does it ever make sense to register more than one
|
| } |
| void VRDisplay::cancelAnimationFrame(int id) { |
| - if (Document* document = m_navigatorVR->document()) |
| - document->cancelAnimationFrame(id); |
| + if (!m_scriptedAnimationController) |
| + return; |
| + m_scriptedAnimationController->cancelCallback(id); |
| +} |
| + |
| +void VRDisplay::serviceScriptedAnimations(double monotonicAnimationStartTime) { |
| + if (!m_scriptedAnimationController) |
| + return; |
| + m_animationCallbackRequested = false; |
| + m_inAnimationFrame = true; |
|
Sami
2016/10/24 10:12:23
nit: Could use AutoReset here.
|
| + m_scriptedAnimationController->serviceScriptedAnimations( |
| + monotonicAnimationStartTime); |
| + m_inAnimationFrame = false; |
| } |
| void ReportPresentationResult(PresentationResult result) { |
| @@ -376,8 +415,28 @@ HeapVector<VRLayer> VRDisplay::getLayers() { |
| } |
| void VRDisplay::submitFrame() { |
| - if (!m_isPresenting || !m_contextGL) { |
| - // Something got confused, we can't submit frames if we're not presenting. |
| + Document* doc = m_navigatorVR->document(); |
| + if (!m_isPresenting) { |
| + if (doc) { |
| + doc->addConsoleMessage(ConsoleMessage::create( |
| + RenderingMessageSource, WarningMessageLevel, |
| + "submitFrame has no effect when the VRDisplay is not presenting.")); |
| + } |
| + return; |
| + } |
| + |
| + if (!m_inAnimationFrame) { |
| + if (doc) { |
| + doc->addConsoleMessage( |
| + ConsoleMessage::create(RenderingMessageSource, WarningMessageLevel, |
| + "submitFrame must be called within a " |
| + "VRDisplay.requestAnimationFrame callback.")); |
| + } |
| + return; |
| + } |
| + |
| + if (!m_contextGL) { |
| + // Something got confused, we can't submit frames without a GL context. |
| return; |
| } |
| @@ -427,6 +486,20 @@ void VRDisplay::onFullscreenCheck(TimerBase*) { |
| } |
| } |
| +ScriptedAnimationController& VRDisplay::ensureScriptedAnimationController( |
| + Document* doc) { |
| + if (!m_scriptedAnimationController) { |
| + m_scriptedAnimationController = ScriptedAnimationController::create(doc); |
| + // We need to make sure that we don't start up the animation controller on a |
|
Sami
2016/10/24 10:12:23
Should this be a TODO since we're not resuming the
|
| + // background tab, for example. |
| + |
| + if (!doc->page()) |
| + m_scriptedAnimationController->suspend(); |
| + } |
| + |
| + return *m_scriptedAnimationController; |
| +} |
| + |
| DEFINE_TRACE(VRDisplay) { |
| visitor->trace(m_navigatorVR); |
| visitor->trace(m_capabilities); |
| @@ -435,6 +508,7 @@ DEFINE_TRACE(VRDisplay) { |
| visitor->trace(m_eyeParametersRight); |
| visitor->trace(m_layer); |
| visitor->trace(m_renderingContext); |
| + visitor->trace(m_scriptedAnimationController); |
| } |
| } // namespace blink |