Add telemetry for reporting graphics driver startup states. (bug 1168935 part 2, r=vdjeric,mattwoodrow)

This commit is contained in:
David Anderson 2015-06-12 01:01:22 -07:00
parent 3a6ee37e8b
commit 1c859963ca
3 changed files with 67 additions and 18 deletions

View File

@ -10,6 +10,7 @@
#include "nsString.h"
#include "nsXULAppAPI.h"
#include "mozilla/Preferences.h"
#include "mozilla/Telemetry.h"
#include "mozilla/gfx/Logging.h"
namespace mozilla {
@ -21,30 +22,32 @@ bool DriverInitCrashDetection::sEnvironmentHasBeenUpdated = false;
DriverInitCrashDetection::DriverInitCrashDetection()
: mIsChromeProcess(XRE_GetProcessType() == GeckoProcessType_Default)
{
// Only use the lockfile in the privileged process, which is responsible for
// the first driver initialization run. Child processes can't access the
// filesystme anyway.
if (mIsChromeProcess && !InitLockFilePath()) {
if (sDisableAcceleration) {
// We already disabled acceleration earlier.
return;
}
if (!mIsChromeProcess) {
// In child processes we only need to check the pref state set by the
// parent process.
sDisableAcceleration = (gfxPrefs::DriverInitStatus() == int32_t(DriverInitStatus::Recovered));
return;
}
if (!InitLockFilePath()) {
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "Failed to create the graphics startup lockfile.";
return;
}
if (RecoverFromDriverInitCrash()) {
if (!sDisableAcceleration) {
// This is the first time we're checking for a crash recovery, so print
// a message and disable acceleration for anyone who asks for it.
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "Recovered from graphics driver startup crash; acceleration disabled.";
sDisableAcceleration = true;
}
// This is the first time we're checking for a crash recovery, so print
// a message and disable acceleration for anyone who asks for it.
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "Recovered from graphics driver startup crash; acceleration disabled.";
sDisableAcceleration = true;
return;
}
// If we previously disabled acceleration, we should have gone through
// RecoverFromDriverInitCrash().
MOZ_ASSERT(!sDisableAcceleration);
if (mIsChromeProcess &&
(UpdateEnvironment() || sEnvironmentHasBeenUpdated))
{
if (UpdateEnvironment() || sEnvironmentHasBeenUpdated) {
// Something in the environment changed, *or* a previous instance of this
// class already updated the environment. Allow a fresh attempt at driver
// acceleration. This doesn't mean the previous attempt failed, it just
@ -53,6 +56,8 @@ DriverInitCrashDetection::DriverInitCrashDetection()
sEnvironmentHasBeenUpdated = true;
return;
}
RecordTelemetry(TelemetryState::Okay);
}
DriverInitCrashDetection::~DriverInitCrashDetection()
@ -65,7 +70,6 @@ DriverInitCrashDetection::~DriverInitCrashDetection()
// If we attempted to initialize the driver, and got this far without
// crashing, assume everything is okay.
gfxPrefs::SetDriverInitStatus(int32_t(DriverInitStatus::Okay));
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "Successfully verified new graphics environment.";
}
}
@ -96,6 +100,10 @@ DriverInitCrashDetection::AllowDriverInitAttempt()
// Flush preferences, so if we crash, we don't think the environment has changed again.
FlushPreferences();
// If we crash, we'll just lose this. Not a big deal, next startup we'll
// record the failure.
RecordTelemetry(TelemetryState::EnvironmentChanged);
}
bool
@ -113,11 +121,13 @@ DriverInitCrashDetection::RecoverFromDriverInitCrash()
gfxPrefs::SetDriverInitStatus(int32_t(DriverInitStatus::Recovered));
UpdateEnvironment();
FlushPreferences();
RecordTelemetry(TelemetryState::RecoveredFromCrash);
return true;
}
if (gfxPrefs::DriverInitStatus() == int32_t(DriverInitStatus::Recovered)) {
// If we get here, we crashed in the current environment and have already
// disabled acceleration.
RecordTelemetry(TelemetryState::AccelerationDisabled);
return true;
}
return false;
@ -204,5 +214,25 @@ DriverInitCrashDetection::FlushPreferences()
}
}
void
DriverInitCrashDetection::RecordTelemetry(TelemetryState aState)
{
// Since we run this in each child process, we only want the initial results
// from the chrome process.
if (XRE_GetProcessType() != GeckoProcessType_Default) {
return;
}
// Since we instantiate this class more than once, make sure we only record
// the first state (since that is really all we care about).
static bool sTelemetryStateRecorded = false;
if (sTelemetryStateRecorded) {
return;
}
Telemetry::Accumulate(Telemetry::GRAPHICS_DRIVER_STARTUP_TEST, int32_t(aState));
sTelemetryStateRecorded = true;
}
} // namespace gfx
} // namespace mozilla

View File

@ -38,6 +38,15 @@ public:
return sDisableAcceleration;
}
// These are the values reported to Telemetry (GRAPHICS_DRIVER_STARTUP_TEST).
// Values should not change; add new values to the end.
enum class TelemetryState {
Okay = 0,
EnvironmentChanged = 1,
RecoveredFromCrash = 2,
AccelerationDisabled = 3
};
private:
bool InitLockFilePath();
bool UpdateEnvironment();
@ -48,6 +57,8 @@ private:
bool RecoverFromDriverInitCrash();
void FlushPreferences();
void RecordTelemetry(TelemetryState aState);
private:
static bool sDisableAcceleration;
static bool sEnvironmentHasBeenUpdated;

View File

@ -8200,5 +8200,13 @@
"expires_in_version": "45",
"kind": "boolean",
"description": "Set if media.eme.enabled is false, in a build that supports the Adobe Primetime Content Decryption Module."
},
"GRAPHICS_DRIVER_STARTUP_TEST": {
"alert_emails": ["danderson@mozilla.com"],
"expires_in_version": "never",
"kind": "enumerated",
"n_values": 20,
"releaseChannelCollection": "opt-out",
"description": "Reports whether or not graphics drivers crashed during startup."
}
}