DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (2cd3752963fc)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
/* -*- 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 http://mozilla.org/MPL/2.0/. */

#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)
#define D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION 2048
#define D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION 4096
#endif

struct ID3D11Device;
struct IDirectDraw7;

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

namespace gfx {
class FeatureState;

class DeviceManagerDx final
{
public:
  static void Init();
  static void Shutdown();

  DeviceManagerDx();

  static DeviceManagerDx* Get() {
    return sInstance;
  }

  RefPtr<ID3D11Device> GetCompositorDevice();
  RefPtr<ID3D11Device> GetContentDevice();
  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
  // D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX and also
  // 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);

private:
  // 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();

  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);

private:
  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> 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