|
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 GFX_DEVICEMANAGERD3D9_H |
|
7 #define GFX_DEVICEMANAGERD3D9_H |
|
8 |
|
9 #include "gfxTypes.h" |
|
10 #include "nsAutoPtr.h" |
|
11 #include "d3d9.h" |
|
12 #include "nsTArray.h" |
|
13 #include "mozilla/layers/CompositorTypes.h" |
|
14 #include "mozilla/RefPtr.h" |
|
15 |
|
16 struct nsIntRect; |
|
17 |
|
18 namespace mozilla { |
|
19 namespace layers { |
|
20 |
|
21 class DeviceManagerD3D9; |
|
22 class LayerD3D9; |
|
23 class Nv3DVUtils; |
|
24 class Layer; |
|
25 class TextureSourceD3D9; |
|
26 |
|
27 // Shader Constant locations |
|
28 const int CBmLayerTransform = 0; |
|
29 const int CBmProjection = 4; |
|
30 const int CBvRenderTargetOffset = 8; |
|
31 const int CBvTextureCoords = 9; |
|
32 const int CBvLayerQuad = 10; |
|
33 // we don't use opacity with solid color shaders |
|
34 const int CBfLayerOpacity = 0; |
|
35 const int CBvColor = 0; |
|
36 |
|
37 enum DeviceManagerState { |
|
38 // The device and swap chain are OK. |
|
39 DeviceOK, |
|
40 // The device or swap chain are in a bad state, and we should not render. |
|
41 DeviceFail, |
|
42 // The device is lost and cannot be reset, the user should forget the |
|
43 // current device manager and create a new one. |
|
44 DeviceMustRecreate, |
|
45 }; |
|
46 |
|
47 |
|
48 /** |
|
49 * This structure is used to pass rectangles to our shader constant. We can use |
|
50 * this for passing rectangular areas to SetVertexShaderConstant. In the format |
|
51 * of a 4 component float(x,y,width,height). Our vertex shader can then use |
|
52 * this to construct rectangular positions from the 0,0-1,1 quad that we source |
|
53 * it with. |
|
54 */ |
|
55 struct ShaderConstantRect |
|
56 { |
|
57 float mX, mY, mWidth, mHeight; |
|
58 |
|
59 // Provide all the commonly used argument types to prevent all the local |
|
60 // casts in the code. |
|
61 ShaderConstantRect(float aX, float aY, float aWidth, float aHeight) |
|
62 : mX(aX), mY(aY), mWidth(aWidth), mHeight(aHeight) |
|
63 { } |
|
64 |
|
65 ShaderConstantRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight) |
|
66 : mX((float)aX), mY((float)aY) |
|
67 , mWidth((float)aWidth), mHeight((float)aHeight) |
|
68 { } |
|
69 |
|
70 ShaderConstantRect(int32_t aX, int32_t aY, float aWidth, float aHeight) |
|
71 : mX((float)aX), mY((float)aY), mWidth(aWidth), mHeight(aHeight) |
|
72 { } |
|
73 |
|
74 // For easy passing to SetVertexShaderConstantF. |
|
75 operator float* () { return &mX; } |
|
76 }; |
|
77 |
|
78 /** |
|
79 * SwapChain class, this class manages the swap chain belonging to a |
|
80 * LayerManagerD3D9. |
|
81 */ |
|
82 class SwapChainD3D9 MOZ_FINAL |
|
83 { |
|
84 NS_INLINE_DECL_REFCOUNTING(SwapChainD3D9) |
|
85 public: |
|
86 |
|
87 /** |
|
88 * This function will prepare the device this swap chain belongs to for |
|
89 * rendering to this swap chain. Only after calling this function can the |
|
90 * swap chain be drawn to, and only until this function is called on another |
|
91 * swap chain belonging to this device will the device draw to it. Passed in |
|
92 * is the size of the swap chain. If the window size differs from the size |
|
93 * during the last call to this function the swap chain will resize. Note that |
|
94 * in no case does this function guarantee the backbuffer to still have its |
|
95 * old content. |
|
96 */ |
|
97 DeviceManagerState PrepareForRendering(); |
|
98 |
|
99 already_AddRefed<IDirect3DSurface9> GetBackBuffer(); |
|
100 |
|
101 /** |
|
102 * This function will present the selected rectangle of the swap chain to |
|
103 * its associated window. |
|
104 */ |
|
105 void Present(const nsIntRect &aRect); |
|
106 void Present(); |
|
107 |
|
108 private: |
|
109 friend class DeviceManagerD3D9; |
|
110 |
|
111 SwapChainD3D9(DeviceManagerD3D9 *aDeviceManager); |
|
112 |
|
113 // Private destructor, to discourage deletion outside of Release(): |
|
114 ~SwapChainD3D9(); |
|
115 |
|
116 bool Init(HWND hWnd); |
|
117 |
|
118 /** |
|
119 * This causes us to release our swap chain, clearing out our resource usage |
|
120 * so the master device may reset. |
|
121 */ |
|
122 void Reset(); |
|
123 |
|
124 nsRefPtr<IDirect3DSwapChain9> mSwapChain; |
|
125 nsRefPtr<DeviceManagerD3D9> mDeviceManager; |
|
126 HWND mWnd; |
|
127 }; |
|
128 |
|
129 /** |
|
130 * Device manager, this class is used by the layer managers to share the D3D9 |
|
131 * device and create swap chains for the individual windows the layer managers |
|
132 * belong to. |
|
133 */ |
|
134 class DeviceManagerD3D9 MOZ_FINAL |
|
135 { |
|
136 public: |
|
137 DeviceManagerD3D9(); |
|
138 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DeviceManagerD3D9) |
|
139 |
|
140 /** |
|
141 * Initialises the device manager, the underlying device, and everything else |
|
142 * the manager needs. |
|
143 * Returns true if initialisation succeeds, false otherwise. |
|
144 * Note that if initisalisation fails, you cannot try again - you must throw |
|
145 * away the DeviceManagerD3D9 and create a new one. |
|
146 */ |
|
147 bool Init(); |
|
148 |
|
149 /** |
|
150 * Sets up the render state for the device for layer rendering. |
|
151 */ |
|
152 void SetupRenderState(); |
|
153 |
|
154 /** |
|
155 * Create a swap chain setup to work with the specified window. |
|
156 */ |
|
157 already_AddRefed<SwapChainD3D9> CreateSwapChain(HWND hWnd); |
|
158 |
|
159 IDirect3DDevice9 *device() { return mDevice; } |
|
160 |
|
161 bool IsD3D9Ex() { return mDeviceEx; } |
|
162 |
|
163 bool HasDynamicTextures() { return mHasDynamicTextures; } |
|
164 |
|
165 enum ShaderMode { |
|
166 RGBLAYER, |
|
167 RGBALAYER, |
|
168 COMPONENTLAYERPASS1, |
|
169 COMPONENTLAYERPASS2, |
|
170 YCBCRLAYER, |
|
171 SOLIDCOLORLAYER |
|
172 }; |
|
173 |
|
174 void SetShaderMode(ShaderMode aMode, Layer* aMask, bool aIs2D); |
|
175 // returns the register to be used for the mask texture, if appropriate |
|
176 uint32_t SetShaderMode(ShaderMode aMode, MaskType aMaskType); |
|
177 |
|
178 /** |
|
179 * Return pointer to the Nv3DVUtils instance |
|
180 */ |
|
181 Nv3DVUtils *GetNv3DVUtils() { return mNv3DVUtils; } |
|
182 |
|
183 /** |
|
184 * Returns true if this device was removed. |
|
185 */ |
|
186 bool DeviceWasRemoved() { return mDeviceWasRemoved; } |
|
187 |
|
188 uint32_t GetDeviceResetCount() { return mDeviceResetCount; } |
|
189 |
|
190 /** |
|
191 * We keep a list of all layers here that may have hardware resource allocated |
|
192 * so we can clean their resources on reset. |
|
193 */ |
|
194 nsTArray<LayerD3D9*> mLayersWithResources; |
|
195 |
|
196 int32_t GetMaxTextureSize() { return mMaxTextureSize; } |
|
197 |
|
198 // Removes aHost from our list of texture hosts if it is the head. |
|
199 void RemoveTextureListHead(TextureSourceD3D9* aHost); |
|
200 |
|
201 /** |
|
202 * Creates a texture using our device. |
|
203 * If needed, we keep a record of the new texture, so the texture can be |
|
204 * released. In this case, aTextureHostIDirect3DTexture9 must be non-null. |
|
205 */ |
|
206 TemporaryRef<IDirect3DTexture9> CreateTexture(const gfx::IntSize &aSize, |
|
207 _D3DFORMAT aFormat, |
|
208 D3DPOOL aPool, |
|
209 TextureSourceD3D9* aTextureHostIDirect3DTexture9); |
|
210 #ifdef DEBUG |
|
211 // Looks for aFind in the list of texture hosts. |
|
212 // O(n) so only use for assertions. |
|
213 bool IsInTextureHostList(TextureSourceD3D9* aFind); |
|
214 #endif |
|
215 |
|
216 /** |
|
217 * This function verifies the device is ready for rendering, internally this |
|
218 * will test the cooperative level of the device and reset the device if |
|
219 * needed. If this returns false subsequent rendering calls may return errors. |
|
220 */ |
|
221 DeviceManagerState VerifyReadyForRendering(); |
|
222 |
|
223 static uint32_t sMaskQuadRegister; |
|
224 |
|
225 private: |
|
226 friend class SwapChainD3D9; |
|
227 |
|
228 ~DeviceManagerD3D9(); |
|
229 void DestroyDevice(); |
|
230 |
|
231 /** |
|
232 * This will fill our vertex buffer with the data of our quad, it may be |
|
233 * called when the vertex buffer is recreated. |
|
234 */ |
|
235 bool CreateVertexBuffer(); |
|
236 |
|
237 /** |
|
238 * Release all textures created by this device manager. |
|
239 */ |
|
240 void ReleaseTextureResources(); |
|
241 /** |
|
242 * Add aHost to our list of texture hosts. |
|
243 */ |
|
244 void RegisterTextureHost(TextureSourceD3D9* aHost); |
|
245 |
|
246 /* Array used to store all swap chains for device resets */ |
|
247 nsTArray<SwapChainD3D9*> mSwapChains; |
|
248 |
|
249 /* The D3D device we use */ |
|
250 nsRefPtr<IDirect3DDevice9> mDevice; |
|
251 |
|
252 /* The D3D9Ex device - only valid on Vista+ with WDDM */ |
|
253 nsRefPtr<IDirect3DDevice9Ex> mDeviceEx; |
|
254 |
|
255 /* An instance of the D3D9 object */ |
|
256 nsRefPtr<IDirect3D9> mD3D9; |
|
257 |
|
258 /* An instance of the D3D9Ex object - only valid on Vista+ with WDDM */ |
|
259 nsRefPtr<IDirect3D9Ex> mD3D9Ex; |
|
260 |
|
261 /* Vertex shader used for layer quads */ |
|
262 nsRefPtr<IDirect3DVertexShader9> mLayerVS; |
|
263 |
|
264 /* Pixel shader used for RGB textures */ |
|
265 nsRefPtr<IDirect3DPixelShader9> mRGBPS; |
|
266 |
|
267 /* Pixel shader used for RGBA textures */ |
|
268 nsRefPtr<IDirect3DPixelShader9> mRGBAPS; |
|
269 |
|
270 /* Pixel shader used for component alpha textures (pass 1) */ |
|
271 nsRefPtr<IDirect3DPixelShader9> mComponentPass1PS; |
|
272 |
|
273 /* Pixel shader used for component alpha textures (pass 2) */ |
|
274 nsRefPtr<IDirect3DPixelShader9> mComponentPass2PS; |
|
275 |
|
276 /* Pixel shader used for RGB textures */ |
|
277 nsRefPtr<IDirect3DPixelShader9> mYCbCrPS; |
|
278 |
|
279 /* Pixel shader used for solid colors */ |
|
280 nsRefPtr<IDirect3DPixelShader9> mSolidColorPS; |
|
281 |
|
282 /* As above, but using a mask layer */ |
|
283 nsRefPtr<IDirect3DVertexShader9> mLayerVSMask; |
|
284 nsRefPtr<IDirect3DVertexShader9> mLayerVSMask3D; |
|
285 nsRefPtr<IDirect3DPixelShader9> mRGBPSMask; |
|
286 nsRefPtr<IDirect3DPixelShader9> mRGBAPSMask; |
|
287 nsRefPtr<IDirect3DPixelShader9> mRGBAPSMask3D; |
|
288 nsRefPtr<IDirect3DPixelShader9> mComponentPass1PSMask; |
|
289 nsRefPtr<IDirect3DPixelShader9> mComponentPass2PSMask; |
|
290 nsRefPtr<IDirect3DPixelShader9> mYCbCrPSMask; |
|
291 nsRefPtr<IDirect3DPixelShader9> mSolidColorPSMask; |
|
292 |
|
293 /* Vertex buffer containing our basic vertex structure */ |
|
294 nsRefPtr<IDirect3DVertexBuffer9> mVB; |
|
295 |
|
296 /* Our vertex declaration */ |
|
297 nsRefPtr<IDirect3DVertexDeclaration9> mVD; |
|
298 |
|
299 /* We maintain a doubly linked list of all d3d9 texture hosts which host |
|
300 * d3d9 textures created by this device manager. |
|
301 * Texture hosts must remove themselves when they disappear (i.e., we |
|
302 * expect all hosts in the list to be valid). |
|
303 * The list is cleared when we release the textures. |
|
304 */ |
|
305 TextureSourceD3D9* mTextureHostList; |
|
306 |
|
307 /* Our focus window - this is really a dummy window we can associate our |
|
308 * device with. |
|
309 */ |
|
310 HWND mFocusWnd; |
|
311 |
|
312 /* we use this to help track if our device temporarily or permanently lost */ |
|
313 HMONITOR mDeviceMonitor; |
|
314 |
|
315 uint32_t mDeviceResetCount; |
|
316 |
|
317 uint32_t mMaxTextureSize; |
|
318 |
|
319 /** |
|
320 * Wrap (repeat) or clamp textures. We prefer the former so we can do buffer |
|
321 * rotation, but some older hardware doesn't support it. |
|
322 */ |
|
323 D3DTEXTUREADDRESS mTextureAddressingMode; |
|
324 |
|
325 /* If this device supports dynamic textures */ |
|
326 bool mHasDynamicTextures; |
|
327 |
|
328 /* If this device was removed */ |
|
329 bool mDeviceWasRemoved; |
|
330 |
|
331 /* Nv3DVUtils instance */ |
|
332 nsAutoPtr<Nv3DVUtils> mNv3DVUtils; |
|
333 |
|
334 /** |
|
335 * Verifies all required device capabilities are present. |
|
336 */ |
|
337 bool VerifyCaps(); |
|
338 }; |
|
339 |
|
340 } /* namespace layers */ |
|
341 } /* namespace mozilla */ |
|
342 |
|
343 #endif /* GFX_DEVICEMANAGERD3D9_H */ |