Blame gfx/src/DriverCrashGuard.h

Packit f0b94e
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
Packit f0b94e
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
Packit f0b94e
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit f0b94e
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit f0b94e
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit f0b94e
#ifndef gfx_src_DriverCrashGuard_h__
Packit f0b94e
#define gfx_src_DriverCrashGuard_h__
Packit f0b94e
Packit f0b94e
#include "nsCOMPtr.h"
Packit f0b94e
#include "nsIGfxInfo.h"
Packit f0b94e
#include "nsIFile.h"
Packit f0b94e
#include "nsString.h"
Packit f0b94e
#include <functional>
Packit f0b94e
#include <string>
Packit f0b94e
Packit f0b94e
namespace mozilla {
Packit f0b94e
Packit f0b94e
namespace dom {
Packit f0b94e
class ContentParent;
Packit f0b94e
}  // namespace dom
Packit f0b94e
Packit f0b94e
namespace gfx {
Packit f0b94e
Packit f0b94e
enum class DriverInitStatus {
Packit f0b94e
  // Drivers have not been initialized yet.
Packit f0b94e
  Unknown,
Packit f0b94e
Packit f0b94e
  // We're attempting to initialize drivers.
Packit f0b94e
  Attempting,
Packit f0b94e
Packit f0b94e
  // Drivers were successfully initialized last run.
Packit f0b94e
  Okay,
Packit f0b94e
Packit f0b94e
  // We crashed during driver initialization, and have restarted.
Packit f0b94e
  Crashed
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
enum class CrashGuardType : uint32_t {
Packit f0b94e
  D3D11Layers,
Packit f0b94e
  D3D9Video,
Packit f0b94e
  GLContext,
Packit f0b94e
  D3D11Video,
Packit f0b94e
  WMFVPXVideo,
Packit f0b94e
  // Add new entries above this line, update the name array in
Packit f0b94e
  // DriverCrashGuard.cpp, and make sure to add an entry in
Packit f0b94e
  // ContentParent.cpp.
Packit f0b94e
Packit f0b94e
  NUM_TYPES
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
// DriverCrashGuard is used to detect crashes at graphics driver callsites.
Packit f0b94e
//
Packit f0b94e
// If the graphics environment is unrecognized or has changed since the last
Packit f0b94e
// session, the crash guard will activate and will detect any crashes within
Packit f0b94e
// the scope of the guard object.
Packit f0b94e
//
Packit f0b94e
// If a callsite has a previously encountered crash, and the environment has
Packit f0b94e
// not changed since the last session, then the guard will set a status flag
Packit f0b94e
// indicating that the driver should not be used.
Packit f0b94e
class DriverCrashGuard {
Packit f0b94e
 public:
Packit f0b94e
  DriverCrashGuard(CrashGuardType aType, dom::ContentParent* aContentParent);
Packit f0b94e
  virtual ~DriverCrashGuard();
Packit f0b94e
Packit f0b94e
  bool Crashed();
Packit f0b94e
  void NotifyCrashed();
Packit f0b94e
Packit f0b94e
  // These are the values reported to Telemetry (GRAPHICS_DRIVER_STARTUP_TEST).
Packit f0b94e
  // Values should not change; add new values to the end.
Packit f0b94e
  enum class TelemetryState {
Packit f0b94e
    Okay = 0,
Packit f0b94e
    EnvironmentChanged = 1,
Packit f0b94e
    RecoveredFromCrash = 2,
Packit f0b94e
    FeatureDisabled = 3
Packit f0b94e
  };
Packit f0b94e
Packit f0b94e
  enum class Mode {
Packit f0b94e
    // Normal operation.
Packit f0b94e
    Normal,
Packit f0b94e
Packit f0b94e
    // Acting as a proxy between the parent and child process.
Packit f0b94e
    Proxy
Packit f0b94e
  };
Packit f0b94e
Packit f0b94e
  typedef std::function<void(const char* aName, const char* aPrefName)>
Packit f0b94e
      CrashGuardCallback;
Packit f0b94e
  static void ForEachActiveCrashGuard(const CrashGuardCallback& aCallback);
Packit f0b94e
Packit f0b94e
 protected:
Packit f0b94e
  virtual void Initialize();
Packit f0b94e
  // UpdateEnvironment needs to return true should we need to attempt the
Packit f0b94e
  // operation once again.
Packit f0b94e
  // It should return true once only so that in case of a crash, we won't
Packit f0b94e
  // needlessly attempt the operation over and over again leading to continual
Packit f0b94e
  // crashes. several times
Packit f0b94e
  virtual bool UpdateEnvironment() {
Packit f0b94e
    // We don't care about any extra preferences here.
Packit f0b94e
    return false;
Packit f0b94e
  }
Packit f0b94e
  virtual void LogCrashRecovery() = 0;
Packit f0b94e
  virtual void LogFeatureDisabled() = 0;
Packit f0b94e
Packit f0b94e
  // Helper functions.
Packit f0b94e
  bool FeatureEnabled(int aFeature, bool aDefault = true);
Packit f0b94e
  bool CheckAndUpdatePref(const char* aPrefName,
Packit f0b94e
                          const nsAString& aCurrentValue);
Packit f0b94e
  bool CheckAndUpdateBoolPref(const char* aPrefName, bool aCurrentValue);
Packit f0b94e
  std::string GetFullPrefName(const char* aPref);
Packit f0b94e
Packit f0b94e
 private:
Packit f0b94e
  // Either process.
Packit f0b94e
  void InitializeIfNeeded();
Packit f0b94e
  bool CheckOrRefreshEnvironment();
Packit f0b94e
  bool UpdateBaseEnvironment();
Packit f0b94e
  DriverInitStatus GetStatus() const;
Packit f0b94e
Packit f0b94e
  // Parent process only.
Packit f0b94e
  nsCOMPtr<nsIFile> GetGuardFile();
Packit f0b94e
  bool RecoverFromCrash();
Packit f0b94e
  void ActivateGuard();
Packit f0b94e
  void FlushPreferences();
Packit f0b94e
  void SetStatus(DriverInitStatus aStatus);
Packit f0b94e
Packit f0b94e
 private:
Packit f0b94e
  CrashGuardType mType;
Packit f0b94e
  Mode mMode;
Packit f0b94e
  bool mInitialized;
Packit f0b94e
  bool mGuardActivated;
Packit f0b94e
  bool mCrashDetected;
Packit f0b94e
  nsCOMPtr<nsIFile> mGuardFile;
Packit f0b94e
Packit f0b94e
 protected:
Packit f0b94e
  nsCString mStatusPref;
Packit f0b94e
  nsCOMPtr<nsIGfxInfo> mGfxInfo;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
class D3D11LayersCrashGuard final : public DriverCrashGuard {
Packit f0b94e
 public:
Packit f0b94e
  explicit D3D11LayersCrashGuard(dom::ContentParent* aContentParent = nullptr);
Packit f0b94e
Packit f0b94e
 protected:
Packit f0b94e
  void Initialize() override;
Packit f0b94e
  bool UpdateEnvironment() override;
Packit f0b94e
  void LogCrashRecovery() override;
Packit f0b94e
  void LogFeatureDisabled() override;
Packit f0b94e
Packit f0b94e
 private:
Packit f0b94e
  void RecordTelemetry(TelemetryState aState);
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
class D3D9VideoCrashGuard final : public DriverCrashGuard {
Packit f0b94e
 public:
Packit f0b94e
  explicit D3D9VideoCrashGuard(dom::ContentParent* aContentParent = nullptr);
Packit f0b94e
Packit f0b94e
 protected:
Packit f0b94e
  void LogCrashRecovery() override;
Packit f0b94e
  void LogFeatureDisabled() override;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
class D3D11VideoCrashGuard final : public DriverCrashGuard {
Packit f0b94e
 public:
Packit f0b94e
  explicit D3D11VideoCrashGuard(dom::ContentParent* aContentParent = nullptr);
Packit f0b94e
Packit f0b94e
 protected:
Packit f0b94e
  void LogCrashRecovery() override;
Packit f0b94e
  void LogFeatureDisabled() override;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
class GLContextCrashGuard final : public DriverCrashGuard {
Packit f0b94e
 public:
Packit f0b94e
  explicit GLContextCrashGuard(dom::ContentParent* aContentParent = nullptr);
Packit f0b94e
  void Initialize() override;
Packit f0b94e
Packit f0b94e
 protected:
Packit f0b94e
  bool UpdateEnvironment() override;
Packit f0b94e
  void LogCrashRecovery() override;
Packit f0b94e
  void LogFeatureDisabled() override;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
class WMFVPXVideoCrashGuard final : public DriverCrashGuard {
Packit f0b94e
 public:
Packit f0b94e
  explicit WMFVPXVideoCrashGuard(dom::ContentParent* aContentParent = nullptr);
Packit f0b94e
Packit f0b94e
 protected:
Packit f0b94e
  void LogCrashRecovery() override;
Packit f0b94e
  void LogFeatureDisabled() override;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
}  // namespace gfx
Packit f0b94e
}  // namespace mozilla
Packit f0b94e
Packit f0b94e
#endif  // gfx_src_DriverCrashGuard_h__