author Alex Gaynor <>
Mon, 27 Nov 2017 14:37:34 -0600
changeset 403385 bcc0a91dd43feae18d4bf04d7db3d146035aa416
parent 394486 aee9bf60d3702222448c1ed4da24ed0881036954
child 410660 d328d8eda8e68d669ebc77184c8d8d870cafcb7c
permissions -rw-r--r--
Bug 1407693 - Part 2 - when a child process crashes, write extra annotation data to a pre-opened file descriptor instead of creating a new file; r=gsvelto,rbarker This removes the need for the content process to have permissions to create new files on macOS, allowing more aggressive sandboxing. MozReview-Commit-ID: 8agL5jwxDSL

/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at */

#ifndef mozilla_gfx_thebes_DeviceManagerDx_h
#define mozilla_gfx_thebes_DeviceManagerDx_h

#include "gfxPlatform.h"
#include "gfxTelemetry.h"
#include "mozilla/Maybe.h"
#include "mozilla/Mutex.h"
#include "mozilla/RefPtr.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/gfx/GraphicsMessages.h"
#include "nsTArray.h"
#include "nsWindowsHelpers.h"

#include <windows.h>
#include <objbase.h>

#include <dxgi.h>

// This header is available in the June 2010 SDK and in the Win8 SDK
#include <d3dcommon.h>
// Win 8.0 SDK types we'll need when building using older sdks.
#if !defined(D3D_FEATURE_LEVEL_11_1) // defined in the 8.0 SDK only
#define D3D_FEATURE_LEVEL_11_1 static_cast<D3D_FEATURE_LEVEL>(0xb100)

struct ID3D11Device;
struct IDirectDraw7;

namespace mozilla {
class ScopedGfxFeatureReporter;
namespace layers {
class DeviceAttachmentsD3D11;
class MLGDevice;
} // namespace layers

namespace gfx {
class FeatureState;

class DeviceManagerDx final
  static void Init();
  static void Shutdown();


  static DeviceManagerDx* Get() {
    return sInstance;

  RefPtr<ID3D11Device> GetCompositorDevice();
  RefPtr<ID3D11Device> GetContentDevice();
  RefPtr<ID3D11Device> GetVRDevice();
  RefPtr<ID3D11Device> CreateDecoderDevice();
  RefPtr<layers::MLGDevice> GetMLGDevice();
  IDirectDraw7* GetDirectDraw();

  unsigned GetCompositorFeatureLevel() const;
  bool TextureSharingWorks();
  bool IsWARP();
  bool CanUseNV12();

  // Returns true if we can create a texture with
  // upload texture data during the CreateTexture2D
  // call. This crashes on some devices, so we might
  // need to avoid it.
  bool CanInitializeKeyedMutexTextures();

  // Intel devices on older windows versions seem to occasionally have
  // stability issues when supplying InitData to CreateTexture2D.
  bool HasCrashyInitData();

  bool CreateCompositorDevices();
  void CreateContentDevices();

  void GetCompositorDevices(RefPtr<ID3D11Device>* aOutDevice,
                            RefPtr<layers::DeviceAttachmentsD3D11>* aOutAttachments);

  void ImportDeviceInfo(const D3D11DeviceStatus& aDeviceStatus);
  void ExportDeviceInfo(D3D11DeviceStatus* aOut);

  void ResetDevices();
  void InitializeDirectDraw();

  // Reset and reacquire the devices if a reset has happened.
  // Returns whether a reset occurred not whether reacquiring
  // was successful.
  bool MaybeResetAndReacquireDevices();

  // Test whether we can acquire a DXGI 1.2-compatible adapter. This should
  // only be called on startup before devices are initialized.
  bool CheckRemotePresentSupport();

  // Device reset helpers.
  bool HasDeviceReset(DeviceResetReason* aOutReason = nullptr);

  // Note: these set the cached device reset reason, which will be picked up
  // on the next frame.
  void ForceDeviceReset(ForcedDeviceResetReason aReason);

  // Pre-load any compositor resources that are expensive, and are needed when we
  // attempt to create a compositor.
  static void PreloadAttachmentsOnCompositorThread();

  IDXGIAdapter1 *GetDXGIAdapter();

  void DisableD3D11AfterCrash();

  void CreateCompositorDevice(mozilla::gfx::FeatureState& d3d11);
  bool CreateCompositorDeviceHelper(
      mozilla::gfx::FeatureState& aD3d11,
      IDXGIAdapter1* aAdapter,
      bool aAttemptVideoSupport,
      RefPtr<ID3D11Device>& aOutDevice);

  void CreateWARPCompositorDevice();
  void CreateMLGDevice();
  bool CreateVRDevice();

  mozilla::gfx::FeatureStatus CreateContentDevice();

  bool CreateDevice(IDXGIAdapter* aAdapter,
                    D3D_DRIVER_TYPE aDriverType,
                    UINT aFlags,
                    HRESULT& aResOut,
                    RefPtr<ID3D11Device>& aOutDevice);

  bool ContentAdapterIsParentAdapter(ID3D11Device* device);

  bool LoadD3D11();
  void ReleaseD3D11();

  // Call GetDeviceRemovedReason on each device until one returns
  // a failure.
  bool GetAnyDeviceRemovedReason(DeviceResetReason* aOutReason);

  static StaticAutoPtr<DeviceManagerDx> sInstance;

  // This is assigned during device creation. Afterwards, it is released if
  // devices failed, and "forgotten" if devices succeeded (meaning, we leak
  // the ref and unassign the module).
  nsModuleHandle mD3D11Module;

  mozilla::Mutex mDeviceLock;
  nsTArray<D3D_FEATURE_LEVEL> mFeatureLevels;
  RefPtr<IDXGIAdapter1> mAdapter;
  RefPtr<ID3D11Device> mCompositorDevice;
  RefPtr<ID3D11Device> mContentDevice;
  RefPtr<ID3D11Device> mVRDevice;
  RefPtr<ID3D11Device> mDecoderDevice;
  RefPtr<layers::DeviceAttachmentsD3D11> mCompositorAttachments;
  RefPtr<layers::MLGDevice> mMLGDevice;
  bool mCompositorDeviceSupportsVideo;

  Maybe<D3D11DeviceStatus> mDeviceStatus;

  nsModuleHandle mDirectDrawDLL;
  RefPtr<IDirectDraw7> mDirectDraw;

  Maybe<DeviceResetReason> mDeviceResetReason;

} // namespace gfx
} // namespace mozilla

#endif // mozilla_gfx_thebes_DeviceManagerDx_h