1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  * This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef mozilla_gfx_thebes_DeviceManagerDx_h
7 #define mozilla_gfx_thebes_DeviceManagerDx_h
8 
9 #include "gfxPlatform.h"
10 #include "gfxTelemetry.h"
11 #include "mozilla/Maybe.h"
12 #include "mozilla/Mutex.h"
13 #include "mozilla/RefPtr.h"
14 #include "mozilla/StaticPtr.h"
15 #include "mozilla/gfx/GraphicsMessages.h"
16 #include "nsTArray.h"
17 #include "nsWindowsHelpers.h"
18 
19 #include <windows.h>
20 #include <objbase.h>
21 
22 #include <dxgi.h>
23 
24 // This header is available in the June 2010 SDK and in the Win8 SDK
25 #include <d3dcommon.h>
26 // Win 8.0 SDK types we'll need when building using older sdks.
27 #if !defined(D3D_FEATURE_LEVEL_11_1) // defined in the 8.0 SDK only
28 #define D3D_FEATURE_LEVEL_11_1 static_cast<D3D_FEATURE_LEVEL>(0xb100)
29 #define D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION 2048
30 #define D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION 4096
31 #endif
32 
33 struct ID3D11Device;
34 struct IDirectDraw7;
35 
36 namespace mozilla {
37 class ScopedGfxFeatureReporter;
38 
39 namespace gfx {
40 class FeatureState;
41 
42 class DeviceManagerDx final
43 {
44 public:
45   static void Init();
46   static void Shutdown();
47 
48   DeviceManagerDx();
49 
Get()50   static DeviceManagerDx* Get() {
51     return sInstance;
52   }
53 
54   RefPtr<ID3D11Device> GetCompositorDevice();
55   RefPtr<ID3D11Device> GetContentDevice();
56   RefPtr<ID3D11Device> CreateDecoderDevice();
57   IDirectDraw7* GetDirectDraw();
58 
59   unsigned GetCompositorFeatureLevel() const;
60   bool TextureSharingWorks();
61   bool IsWARP();
62 
63   // Returns true if we can create a texture with
64   // D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX and also
65   // upload texture data during the CreateTexture2D
66   // call. This crashes on some devices, so we might
67   // need to avoid it.
68   bool CanInitializeKeyedMutexTextures();
69 
70   bool CreateCompositorDevices();
71   void CreateContentDevices();
72 
73   void ImportDeviceInfo(const D3D11DeviceStatus& aDeviceStatus);
74   void ExportDeviceInfo(D3D11DeviceStatus* aOut);
75 
76   void ResetDevices();
77   void InitializeDirectDraw();
78 
79   // Reset and reacquire the devices if a reset has happened.
80   // Returns whether a reset occurred not whether reacquiring
81   // was successful.
82   bool MaybeResetAndReacquireDevices();
83 
84   // Test whether we can acquire a DXGI 1.2-compatible adapter. This should
85   // only be called on startup before devices are initialized.
86   bool CheckRemotePresentSupport();
87 
88   // Device reset helpers.
89   bool HasDeviceReset(DeviceResetReason* aOutReason = nullptr);
90 
91   // Note: these set the cached device reset reason, which will be picked up
92   // on the next frame.
93   void ForceDeviceReset(ForcedDeviceResetReason aReason);
94   void NotifyD3D9DeviceReset();
95 
96 private:
97   IDXGIAdapter1 *GetDXGIAdapter();
98 
99   void DisableD3D11AfterCrash();
100 
101   void CreateCompositorDevice(mozilla::gfx::FeatureState& d3d11);
102   bool CreateCompositorDeviceHelper(
103       mozilla::gfx::FeatureState& aD3d11,
104       IDXGIAdapter1* aAdapter,
105       bool aAttemptVideoSupport,
106       RefPtr<ID3D11Device>& aOutDevice);
107 
108   void CreateWARPCompositorDevice();
109 
110   mozilla::gfx::FeatureStatus CreateContentDevice();
111 
112   bool CreateDevice(IDXGIAdapter* aAdapter,
113                     D3D_DRIVER_TYPE aDriverType,
114                     UINT aFlags,
115                     HRESULT& aResOut,
116                     RefPtr<ID3D11Device>& aOutDevice);
117 
118   bool ContentAdapterIsParentAdapter(ID3D11Device* device);
119 
120   bool LoadD3D11();
121   void ReleaseD3D11();
122 
123   // Call GetDeviceRemovedReason on each device until one returns
124   // a failure.
125   bool GetAnyDeviceRemovedReason(DeviceResetReason* aOutReason);
126 
127 private:
128   static StaticAutoPtr<DeviceManagerDx> sInstance;
129 
130   // This is assigned during device creation. Afterwards, it is released if
131   // devices failed, and "forgotten" if devices succeeded (meaning, we leak
132   // the ref and unassign the module).
133   nsModuleHandle mD3D11Module;
134 
135   mozilla::Mutex mDeviceLock;
136   nsTArray<D3D_FEATURE_LEVEL> mFeatureLevels;
137   RefPtr<IDXGIAdapter1> mAdapter;
138   RefPtr<ID3D11Device> mCompositorDevice;
139   RefPtr<ID3D11Device> mContentDevice;
140   RefPtr<ID3D11Device> mDecoderDevice;
141   bool mCompositorDeviceSupportsVideo;
142 
143   Maybe<D3D11DeviceStatus> mDeviceStatus;
144 
145   nsModuleHandle mDirectDrawDLL;
146   RefPtr<IDirectDraw7> mDirectDraw;
147 
148   Maybe<DeviceResetReason> mDeviceResetReason;
149 };
150 
151 } // namespace gfx
152 } // namespace mozilla
153 
154 #endif // mozilla_gfx_thebes_DeviceManagerDx_h
155