Bug 1578851 - Using VRManagerChild to check isPresenting to skip painting in nsRefreshDriver. r=rbarker,imanol,mstange

VRManager only be accessible in the parent or GPU process. So, in the tab process, isPresenting() will always return false. In WebVR immersive mode, we need to skip layer painting and don't need to wait for painting because the compositing is already done in WebGL.

Differential Revision: https://phabricator.services.mozilla.com/D48119
This commit is contained in:
Daosheng Mu
2019-10-24 19:58:15 +00:00
parent b9052f7cfa
commit c9815568a2
5 changed files with 37 additions and 7 deletions

View File

@@ -269,6 +269,10 @@ bool VRDisplayClient::GetIsConnected() const {
return mDisplayInfo.GetIsConnected(); return mDisplayInfo.GetIsConnected();
} }
bool VRDisplayClient::IsPresenting() {
return mDisplayInfo.mPresentingGroups != 0;
}
void VRDisplayClient::NotifyDisconnected() { void VRDisplayClient::NotifyDisconnected() {
mDisplayInfo.mDisplayState.isConnected = false; mDisplayInfo.mDisplayState.isConnected = false;
} }

View File

@@ -48,6 +48,8 @@ class VRDisplayClient {
void StartVRNavigation(); void StartVRNavigation();
void StopVRNavigation(const TimeDuration& aTimeout); void StopVRNavigation(const TimeDuration& aTimeout);
bool IsPresenting();
protected: protected:
virtual ~VRDisplayClient(); virtual ~VRDisplayClient();

View File

@@ -71,6 +71,22 @@ VRManagerChild* VRManagerChild::Get() {
/* static */ /* static */
bool VRManagerChild::IsCreated() { return !!sVRManagerChildSingleton; } bool VRManagerChild::IsCreated() { return !!sVRManagerChildSingleton; }
/* static */
bool VRManagerChild::IsPresenting() {
if (!VRManagerChild::IsCreated()) {
return false;
}
nsTArray<RefPtr<VRDisplayClient>> displays;
sVRManagerChildSingleton->GetVRDisplays(displays);
bool result = false;
for (auto& display : displays) {
result |= display->IsPresenting();
}
return result;
}
/* static */ /* static */
bool VRManagerChild::InitForContent(Endpoint<PVRManagerChild>&& aEndpoint) { bool VRManagerChild::InitForContent(Endpoint<PVRManagerChild>&& aEndpoint) {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());

View File

@@ -73,6 +73,7 @@ class VRManagerChild : public PVRManagerChild {
static void ShutDown(); static void ShutDown();
static bool IsCreated(); static bool IsCreated();
static bool IsPresenting();
PVRLayerChild* CreateVRLayer(uint32_t aDisplayID, nsIEventTarget* aTarget, PVRLayerChild* CreateVRLayer(uint32_t aDisplayID, nsIEventTarget* aTarget,
uint32_t aGroup); uint32_t aGroup);

View File

@@ -82,7 +82,7 @@
#include "nsTransitionManager.h" #include "nsTransitionManager.h"
#if defined(MOZ_WIDGET_ANDROID) #if defined(MOZ_WIDGET_ANDROID)
# include "VRManager.h" # include "VRManagerChild.h"
#endif // defined(MOZ_WIDGET_ANDROID) #endif // defined(MOZ_WIDGET_ANDROID)
#ifdef MOZ_XUL #ifdef MOZ_XUL
@@ -1817,7 +1817,15 @@ void nsRefreshDriver::Tick(VsyncId aId, TimeStamp aNowTime) {
return; return;
} }
if (IsWaitingForPaint(aNowTime)) { bool isPresentingInVR = false;
#if defined(MOZ_WIDGET_ANDROID)
isPresentingInVR = gfx::VRManagerChild::IsPresenting();
#endif // defined(MOZ_WIDGET_ANDROID)
if (!isPresentingInVR && IsWaitingForPaint(aNowTime)) {
// In immersive VR mode, we do not get notifications when frames are
// presented, so we do not wait for the compositor in that mode.
// We're currently suspended waiting for earlier Tick's to // We're currently suspended waiting for earlier Tick's to
// be completed (on the Compositor). Mark that we missed the paint // be completed (on the Compositor). Mark that we missed the paint
// and keep waiting. // and keep waiting.
@@ -2133,11 +2141,10 @@ void nsRefreshDriver::Tick(VsyncId aId, TimeStamp aNowTime) {
mViewManagerFlushIsPending = false; mViewManagerFlushIsPending = false;
RefPtr<nsViewManager> vm = mPresContext->GetPresShell()->GetViewManager(); RefPtr<nsViewManager> vm = mPresContext->GetPresShell()->GetViewManager();
bool skipPaint = false; const bool skipPaint = isPresentingInVR;
#if defined(MOZ_WIDGET_ANDROID) // Skip the paint in immersive VR mode because whatever we paint here will
gfx::VRManager* vrm = gfx::VRManager::Get(); // not end up on the screen. The screen is displaying WebGL content from a
skipPaint = vrm->IsPresenting(); // single canvas in that mode.
#endif // defined(MOZ_WIDGET_ANDROID)
if (!skipPaint) { if (!skipPaint) {
PaintTelemetry::AutoRecordPaint record; PaintTelemetry::AutoRecordPaint record;
vm->ProcessPendingUpdates(); vm->ProcessPendingUpdates();