Bug 1392476 - Add dropframe telemetry for WebVR; r?kip, francois
MozReview-Commit-ID: IPVnPBkY8CN
--- a/gfx/vr/gfxVR.h
+++ b/gfx/vr/gfxVR.h
@@ -306,16 +306,35 @@ struct VRControllerInfo
mNumHaptics == other.mNumHaptics;
}
bool operator!=(const VRControllerInfo& other) const {
return !(*this == other);
}
};
+struct VRTelemetry
+{
+ VRTelemetry()
+ : mLastDroppedFrameCount(-1)
+ {}
+
+ void Clear() {
+ mPresentationStart = TimeStamp();
+ mLastDroppedFrameCount = -1;
+ }
+
+ bool IsLastDroppedFrameValid() {
+ return (mLastDroppedFrameCount != -1);
+ }
+
+ TimeStamp mPresentationStart;
+ int32_t mLastDroppedFrameCount;
+};
+
class VRSystemManager {
public:
static uint32_t AllocateDisplayID();
static uint32_t AllocateControllerID();
protected:
static Atomic<uint32_t> sDisplayBase;
static Atomic<uint32_t> sControllerBase;
--- a/gfx/vr/gfxVROculus.cpp
+++ b/gfx/vr/gfxVROculus.cpp
@@ -228,29 +228,50 @@ VROculusSession::StopTracking()
void
VROculusSession::StartPresentation(const IntSize& aSize)
{
if (!mPresenting) {
mPresenting = true;
mPresentationSize = aSize;
Refresh();
- mPresentationStart = TimeStamp::Now();
+ mTelemetry.Clear();
+ mTelemetry.mPresentationStart = TimeStamp::Now();
+
+ ovrPerfStats perfStats;
+ if (ovr_GetPerfStats(mSession, &perfStats) == ovrSuccess) {
+ if (perfStats.FrameStatsCount) {
+ mTelemetry.mLastDroppedFrameCount = perfStats.FrameStats[0].AppDroppedFrameCount;
+ }
+ }
}
}
void
VROculusSession::StopPresentation()
{
if (mPresenting) {
mLastPresentationEnd = TimeStamp::Now();
mPresenting = false;
+
+ const TimeDuration duration = mLastPresentationEnd - mTelemetry.mPresentationStart;
Telemetry::Accumulate(Telemetry::WEBVR_USERS_VIEW_IN, 1);
- Telemetry::AccumulateTimeDelta(Telemetry::WEBVR_TIME_SPENT_VIEWING_IN_OCULUS,
- mPresentationStart);
+ Telemetry::Accumulate(Telemetry::WEBVR_TIME_SPENT_VIEWING_IN_OCULUS,
+ duration.ToMilliseconds());
+
+ if (mTelemetry.IsLastDroppedFrameValid() && duration.ToSeconds()) {
+ ovrPerfStats perfStats;
+ if (ovr_GetPerfStats(mSession, &perfStats) == ovrSuccess) {
+ if (perfStats.FrameStatsCount) {
+ const uint32_t droppedFramesPerSec = (perfStats.FrameStats[0].AppDroppedFrameCount -
+ mTelemetry.mLastDroppedFrameCount) / duration.ToSeconds();
+ Telemetry::Accumulate(Telemetry::WEBVR_DROPPED_FRAMES_IN_OCULUS, droppedFramesPerSec);
+ }
+ }
+ }
Refresh();
}
}
VROculusSession::~VROculusSession()
{
Uninitialize(true);
}
--- a/gfx/vr/gfxVROculus.h
+++ b/gfx/vr/gfxVROculus.h
@@ -32,16 +32,17 @@ enum class OculusControllerAxisType : ui
ThumbstickXAxis,
ThumbstickYAxis,
NumVRControllerAxisType
};
class VROculusSession
{
NS_INLINE_DECL_REFCOUNTING(VROculusSession);
+ friend class VRDisplayOculus;
public:
VROculusSession();
void Refresh();
bool IsTrackingReady() const;
bool IsRenderReady() const;
ovrSession Get();
void StartPresentation(const IntSize& aSize);
void StopPresentation();
@@ -51,24 +52,24 @@ public:
ovrTextureSwapChain GetSwapChain();
private:
PRLibrary* mOvrLib;
ovrSession mSession;
ovrInitFlags mInitFlags;
ovrTextureSwapChain mTextureSet;
nsTArray<RefPtr<layers::CompositingRenderTargetD3D11>> mRenderTargets;
- bool mPresenting;
IntSize mPresentationSize;
RefPtr<ID3D11Device> mDevice;
// The timestamp of the last time Oculus set ShouldQuit to true.
TimeStamp mLastShouldQuit;
// The timestamp of the last ending presentation
TimeStamp mLastPresentationEnd;
- TimeStamp mPresentationStart;
+ VRTelemetry mTelemetry;
+ bool mPresenting;
~VROculusSession();
void Uninitialize(bool aUnloadLib);
bool Initialize(ovrInitFlags aFlags);
bool LoadOvrLib();
void UnloadOvrLib();
bool StartSession();
void StopSession();
--- a/gfx/vr/gfxVROpenVR.cpp
+++ b/gfx/vr/gfxVROpenVR.cpp
@@ -263,32 +263,44 @@ VRDisplayOpenVR::GetSensorState()
void
VRDisplayOpenVR::StartPresentation()
{
if (mIsPresenting) {
return;
}
mIsPresenting = true;
- mPresentationStart = TimeStamp::Now();
+ mTelemetry.Clear();
+ mTelemetry.mPresentationStart = TimeStamp::Now();
+
+ ::vr::Compositor_CumulativeStats stats;
+ mVRCompositor->GetCumulativeStats(&stats, sizeof(::vr::Compositor_CumulativeStats));
+ mTelemetry.mLastDroppedFrameCount = stats.m_nNumReprojectedFrames;
}
void
VRDisplayOpenVR::StopPresentation()
{
if (!mIsPresenting) {
return;
}
mVRCompositor->ClearLastSubmittedFrame();
mIsPresenting = false;
+ const TimeDuration duration = TimeStamp::Now() - mTelemetry.mPresentationStart;
Telemetry::Accumulate(Telemetry::WEBVR_USERS_VIEW_IN, 2);
- Telemetry::AccumulateTimeDelta(Telemetry::WEBVR_TIME_SPENT_VIEWING_IN_OPENVR,
- mPresentationStart);
+ Telemetry::Accumulate(Telemetry::WEBVR_TIME_SPENT_VIEWING_IN_OPENVR,
+ duration.ToMilliseconds());
+
+ ::vr::Compositor_CumulativeStats stats;
+ mVRCompositor->GetCumulativeStats(&stats, sizeof(::vr::Compositor_CumulativeStats));
+ const uint32_t droppedFramesPerSec = (stats.m_nNumReprojectedFrames -
+ mTelemetry.mLastDroppedFrameCount) / duration.ToSeconds();
+ Telemetry::Accumulate(Telemetry::WEBVR_DROPPED_FRAMES_IN_OPENVR, droppedFramesPerSec);
}
bool
VRDisplayOpenVR::SubmitFrame(void* aTextureHandle,
::vr::ETextureType aTextureType,
const IntSize& aSize,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect)
--- a/gfx/vr/gfxVROpenVR.h
+++ b/gfx/vr/gfxVROpenVR.h
@@ -57,17 +57,17 @@ protected:
virtual ~VRDisplayOpenVR();
void Destroy();
// not owned by us; global from OpenVR
::vr::IVRSystem *mVRSystem;
::vr::IVRChaperone *mVRChaperone;
::vr::IVRCompositor *mVRCompositor;
- TimeStamp mPresentationStart;
+ VRTelemetry mTelemetry;
bool mIsPresenting;
void UpdateStageParameters();
void PollEvents();
bool SubmitFrame(void* aTextureHandle,
::vr::ETextureType aTextureType,
const IntSize& aSize,
const gfx::Rect& aLeftEyeRect,
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -13555,16 +13555,38 @@
"bug_numbers": [1306156],
"expires_in_version": "never",
"kind": "exponential",
"high": 1200000,
"n_buckets": 100,
"releaseChannelCollection": "opt-out",
"description": "The amount of time spent(ms) of a session for viewing content in OpenVR."
},
+ "WEBVR_DROPPED_FRAMES_IN_OCULUS": {
+ "record_in_processes": ["main", "gpu"],
+ "alert_emails": ["dmu@mozilla.com"],
+ "bug_numbers": [1392476],
+ "expires_in_version": "never",
+ "kind": "linear",
+ "high": 200,
+ "n_buckets": 100,
+ "releaseChannelCollection": "opt-out",
+ "description": "The average number of dropped frames per sec in Oculus, sent when user exits WebVR content."
+ },
+ "WEBVR_DROPPED_FRAMES_IN_OPENVR": {
+ "record_in_processes": ["main", "gpu"],
+ "alert_emails": ["dmu@mozilla.com"],
+ "bug_numbers": [1392476],
+ "expires_in_version": "never",
+ "kind": "linear",
+ "high": 200,
+ "n_buckets": 100,
+ "releaseChannelCollection": "opt-out",
+ "description": "The average number of dropped frames per sec in OpenVR, sent when user exits WebVR content."
+ },
"URLCLASSIFIER_UI_EVENTS": {
"record_in_processes": ["main", "content"],
"alert_emails": ["seceng-telemetry@mozilla.com", "francois@mozilla.com"],
"bug_numbers": [1375277],
"expires_in_version": "never",
"kind": "enumerated",
"n_values": 64,
"description": "URL CLassifier-related (aka Safe Browsing) UI events. See nsIUrlClassifierUITelemetry.idl for the specific values."