1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/d3d9/DeviceManagerD3D9.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,343 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef GFX_DEVICEMANAGERD3D9_H 1.10 +#define GFX_DEVICEMANAGERD3D9_H 1.11 + 1.12 +#include "gfxTypes.h" 1.13 +#include "nsAutoPtr.h" 1.14 +#include "d3d9.h" 1.15 +#include "nsTArray.h" 1.16 +#include "mozilla/layers/CompositorTypes.h" 1.17 +#include "mozilla/RefPtr.h" 1.18 + 1.19 +struct nsIntRect; 1.20 + 1.21 +namespace mozilla { 1.22 +namespace layers { 1.23 + 1.24 +class DeviceManagerD3D9; 1.25 +class LayerD3D9; 1.26 +class Nv3DVUtils; 1.27 +class Layer; 1.28 +class TextureSourceD3D9; 1.29 + 1.30 +// Shader Constant locations 1.31 +const int CBmLayerTransform = 0; 1.32 +const int CBmProjection = 4; 1.33 +const int CBvRenderTargetOffset = 8; 1.34 +const int CBvTextureCoords = 9; 1.35 +const int CBvLayerQuad = 10; 1.36 +// we don't use opacity with solid color shaders 1.37 +const int CBfLayerOpacity = 0; 1.38 +const int CBvColor = 0; 1.39 + 1.40 +enum DeviceManagerState { 1.41 + // The device and swap chain are OK. 1.42 + DeviceOK, 1.43 + // The device or swap chain are in a bad state, and we should not render. 1.44 + DeviceFail, 1.45 + // The device is lost and cannot be reset, the user should forget the 1.46 + // current device manager and create a new one. 1.47 + DeviceMustRecreate, 1.48 +}; 1.49 + 1.50 + 1.51 +/** 1.52 + * This structure is used to pass rectangles to our shader constant. We can use 1.53 + * this for passing rectangular areas to SetVertexShaderConstant. In the format 1.54 + * of a 4 component float(x,y,width,height). Our vertex shader can then use 1.55 + * this to construct rectangular positions from the 0,0-1,1 quad that we source 1.56 + * it with. 1.57 + */ 1.58 +struct ShaderConstantRect 1.59 +{ 1.60 + float mX, mY, mWidth, mHeight; 1.61 + 1.62 + // Provide all the commonly used argument types to prevent all the local 1.63 + // casts in the code. 1.64 + ShaderConstantRect(float aX, float aY, float aWidth, float aHeight) 1.65 + : mX(aX), mY(aY), mWidth(aWidth), mHeight(aHeight) 1.66 + { } 1.67 + 1.68 + ShaderConstantRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight) 1.69 + : mX((float)aX), mY((float)aY) 1.70 + , mWidth((float)aWidth), mHeight((float)aHeight) 1.71 + { } 1.72 + 1.73 + ShaderConstantRect(int32_t aX, int32_t aY, float aWidth, float aHeight) 1.74 + : mX((float)aX), mY((float)aY), mWidth(aWidth), mHeight(aHeight) 1.75 + { } 1.76 + 1.77 + // For easy passing to SetVertexShaderConstantF. 1.78 + operator float* () { return &mX; } 1.79 +}; 1.80 + 1.81 +/** 1.82 + * SwapChain class, this class manages the swap chain belonging to a 1.83 + * LayerManagerD3D9. 1.84 + */ 1.85 +class SwapChainD3D9 MOZ_FINAL 1.86 +{ 1.87 + NS_INLINE_DECL_REFCOUNTING(SwapChainD3D9) 1.88 +public: 1.89 + 1.90 + /** 1.91 + * This function will prepare the device this swap chain belongs to for 1.92 + * rendering to this swap chain. Only after calling this function can the 1.93 + * swap chain be drawn to, and only until this function is called on another 1.94 + * swap chain belonging to this device will the device draw to it. Passed in 1.95 + * is the size of the swap chain. If the window size differs from the size 1.96 + * during the last call to this function the swap chain will resize. Note that 1.97 + * in no case does this function guarantee the backbuffer to still have its 1.98 + * old content. 1.99 + */ 1.100 + DeviceManagerState PrepareForRendering(); 1.101 + 1.102 + already_AddRefed<IDirect3DSurface9> GetBackBuffer(); 1.103 + 1.104 + /** 1.105 + * This function will present the selected rectangle of the swap chain to 1.106 + * its associated window. 1.107 + */ 1.108 + void Present(const nsIntRect &aRect); 1.109 + void Present(); 1.110 + 1.111 +private: 1.112 + friend class DeviceManagerD3D9; 1.113 + 1.114 + SwapChainD3D9(DeviceManagerD3D9 *aDeviceManager); 1.115 + 1.116 + // Private destructor, to discourage deletion outside of Release(): 1.117 + ~SwapChainD3D9(); 1.118 + 1.119 + bool Init(HWND hWnd); 1.120 + 1.121 + /** 1.122 + * This causes us to release our swap chain, clearing out our resource usage 1.123 + * so the master device may reset. 1.124 + */ 1.125 + void Reset(); 1.126 + 1.127 + nsRefPtr<IDirect3DSwapChain9> mSwapChain; 1.128 + nsRefPtr<DeviceManagerD3D9> mDeviceManager; 1.129 + HWND mWnd; 1.130 +}; 1.131 + 1.132 +/** 1.133 + * Device manager, this class is used by the layer managers to share the D3D9 1.134 + * device and create swap chains for the individual windows the layer managers 1.135 + * belong to. 1.136 + */ 1.137 +class DeviceManagerD3D9 MOZ_FINAL 1.138 +{ 1.139 +public: 1.140 + DeviceManagerD3D9(); 1.141 + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DeviceManagerD3D9) 1.142 + 1.143 + /** 1.144 + * Initialises the device manager, the underlying device, and everything else 1.145 + * the manager needs. 1.146 + * Returns true if initialisation succeeds, false otherwise. 1.147 + * Note that if initisalisation fails, you cannot try again - you must throw 1.148 + * away the DeviceManagerD3D9 and create a new one. 1.149 + */ 1.150 + bool Init(); 1.151 + 1.152 + /** 1.153 + * Sets up the render state for the device for layer rendering. 1.154 + */ 1.155 + void SetupRenderState(); 1.156 + 1.157 + /** 1.158 + * Create a swap chain setup to work with the specified window. 1.159 + */ 1.160 + already_AddRefed<SwapChainD3D9> CreateSwapChain(HWND hWnd); 1.161 + 1.162 + IDirect3DDevice9 *device() { return mDevice; } 1.163 + 1.164 + bool IsD3D9Ex() { return mDeviceEx; } 1.165 + 1.166 + bool HasDynamicTextures() { return mHasDynamicTextures; } 1.167 + 1.168 + enum ShaderMode { 1.169 + RGBLAYER, 1.170 + RGBALAYER, 1.171 + COMPONENTLAYERPASS1, 1.172 + COMPONENTLAYERPASS2, 1.173 + YCBCRLAYER, 1.174 + SOLIDCOLORLAYER 1.175 + }; 1.176 + 1.177 + void SetShaderMode(ShaderMode aMode, Layer* aMask, bool aIs2D); 1.178 + // returns the register to be used for the mask texture, if appropriate 1.179 + uint32_t SetShaderMode(ShaderMode aMode, MaskType aMaskType); 1.180 + 1.181 + /** 1.182 + * Return pointer to the Nv3DVUtils instance 1.183 + */ 1.184 + Nv3DVUtils *GetNv3DVUtils() { return mNv3DVUtils; } 1.185 + 1.186 + /** 1.187 + * Returns true if this device was removed. 1.188 + */ 1.189 + bool DeviceWasRemoved() { return mDeviceWasRemoved; } 1.190 + 1.191 + uint32_t GetDeviceResetCount() { return mDeviceResetCount; } 1.192 + 1.193 + /** 1.194 + * We keep a list of all layers here that may have hardware resource allocated 1.195 + * so we can clean their resources on reset. 1.196 + */ 1.197 + nsTArray<LayerD3D9*> mLayersWithResources; 1.198 + 1.199 + int32_t GetMaxTextureSize() { return mMaxTextureSize; } 1.200 + 1.201 + // Removes aHost from our list of texture hosts if it is the head. 1.202 + void RemoveTextureListHead(TextureSourceD3D9* aHost); 1.203 + 1.204 + /** 1.205 + * Creates a texture using our device. 1.206 + * If needed, we keep a record of the new texture, so the texture can be 1.207 + * released. In this case, aTextureHostIDirect3DTexture9 must be non-null. 1.208 + */ 1.209 + TemporaryRef<IDirect3DTexture9> CreateTexture(const gfx::IntSize &aSize, 1.210 + _D3DFORMAT aFormat, 1.211 + D3DPOOL aPool, 1.212 + TextureSourceD3D9* aTextureHostIDirect3DTexture9); 1.213 +#ifdef DEBUG 1.214 + // Looks for aFind in the list of texture hosts. 1.215 + // O(n) so only use for assertions. 1.216 + bool IsInTextureHostList(TextureSourceD3D9* aFind); 1.217 +#endif 1.218 + 1.219 + /** 1.220 + * This function verifies the device is ready for rendering, internally this 1.221 + * will test the cooperative level of the device and reset the device if 1.222 + * needed. If this returns false subsequent rendering calls may return errors. 1.223 + */ 1.224 + DeviceManagerState VerifyReadyForRendering(); 1.225 + 1.226 + static uint32_t sMaskQuadRegister; 1.227 + 1.228 +private: 1.229 + friend class SwapChainD3D9; 1.230 + 1.231 + ~DeviceManagerD3D9(); 1.232 + void DestroyDevice(); 1.233 + 1.234 + /** 1.235 + * This will fill our vertex buffer with the data of our quad, it may be 1.236 + * called when the vertex buffer is recreated. 1.237 + */ 1.238 + bool CreateVertexBuffer(); 1.239 + 1.240 + /** 1.241 + * Release all textures created by this device manager. 1.242 + */ 1.243 + void ReleaseTextureResources(); 1.244 + /** 1.245 + * Add aHost to our list of texture hosts. 1.246 + */ 1.247 + void RegisterTextureHost(TextureSourceD3D9* aHost); 1.248 + 1.249 + /* Array used to store all swap chains for device resets */ 1.250 + nsTArray<SwapChainD3D9*> mSwapChains; 1.251 + 1.252 + /* The D3D device we use */ 1.253 + nsRefPtr<IDirect3DDevice9> mDevice; 1.254 + 1.255 + /* The D3D9Ex device - only valid on Vista+ with WDDM */ 1.256 + nsRefPtr<IDirect3DDevice9Ex> mDeviceEx; 1.257 + 1.258 + /* An instance of the D3D9 object */ 1.259 + nsRefPtr<IDirect3D9> mD3D9; 1.260 + 1.261 + /* An instance of the D3D9Ex object - only valid on Vista+ with WDDM */ 1.262 + nsRefPtr<IDirect3D9Ex> mD3D9Ex; 1.263 + 1.264 + /* Vertex shader used for layer quads */ 1.265 + nsRefPtr<IDirect3DVertexShader9> mLayerVS; 1.266 + 1.267 + /* Pixel shader used for RGB textures */ 1.268 + nsRefPtr<IDirect3DPixelShader9> mRGBPS; 1.269 + 1.270 + /* Pixel shader used for RGBA textures */ 1.271 + nsRefPtr<IDirect3DPixelShader9> mRGBAPS; 1.272 + 1.273 + /* Pixel shader used for component alpha textures (pass 1) */ 1.274 + nsRefPtr<IDirect3DPixelShader9> mComponentPass1PS; 1.275 + 1.276 + /* Pixel shader used for component alpha textures (pass 2) */ 1.277 + nsRefPtr<IDirect3DPixelShader9> mComponentPass2PS; 1.278 + 1.279 + /* Pixel shader used for RGB textures */ 1.280 + nsRefPtr<IDirect3DPixelShader9> mYCbCrPS; 1.281 + 1.282 + /* Pixel shader used for solid colors */ 1.283 + nsRefPtr<IDirect3DPixelShader9> mSolidColorPS; 1.284 + 1.285 + /* As above, but using a mask layer */ 1.286 + nsRefPtr<IDirect3DVertexShader9> mLayerVSMask; 1.287 + nsRefPtr<IDirect3DVertexShader9> mLayerVSMask3D; 1.288 + nsRefPtr<IDirect3DPixelShader9> mRGBPSMask; 1.289 + nsRefPtr<IDirect3DPixelShader9> mRGBAPSMask; 1.290 + nsRefPtr<IDirect3DPixelShader9> mRGBAPSMask3D; 1.291 + nsRefPtr<IDirect3DPixelShader9> mComponentPass1PSMask; 1.292 + nsRefPtr<IDirect3DPixelShader9> mComponentPass2PSMask; 1.293 + nsRefPtr<IDirect3DPixelShader9> mYCbCrPSMask; 1.294 + nsRefPtr<IDirect3DPixelShader9> mSolidColorPSMask; 1.295 + 1.296 + /* Vertex buffer containing our basic vertex structure */ 1.297 + nsRefPtr<IDirect3DVertexBuffer9> mVB; 1.298 + 1.299 + /* Our vertex declaration */ 1.300 + nsRefPtr<IDirect3DVertexDeclaration9> mVD; 1.301 + 1.302 + /* We maintain a doubly linked list of all d3d9 texture hosts which host 1.303 + * d3d9 textures created by this device manager. 1.304 + * Texture hosts must remove themselves when they disappear (i.e., we 1.305 + * expect all hosts in the list to be valid). 1.306 + * The list is cleared when we release the textures. 1.307 + */ 1.308 + TextureSourceD3D9* mTextureHostList; 1.309 + 1.310 + /* Our focus window - this is really a dummy window we can associate our 1.311 + * device with. 1.312 + */ 1.313 + HWND mFocusWnd; 1.314 + 1.315 + /* we use this to help track if our device temporarily or permanently lost */ 1.316 + HMONITOR mDeviceMonitor; 1.317 + 1.318 + uint32_t mDeviceResetCount; 1.319 + 1.320 + uint32_t mMaxTextureSize; 1.321 + 1.322 + /** 1.323 + * Wrap (repeat) or clamp textures. We prefer the former so we can do buffer 1.324 + * rotation, but some older hardware doesn't support it. 1.325 + */ 1.326 + D3DTEXTUREADDRESS mTextureAddressingMode; 1.327 + 1.328 + /* If this device supports dynamic textures */ 1.329 + bool mHasDynamicTextures; 1.330 + 1.331 + /* If this device was removed */ 1.332 + bool mDeviceWasRemoved; 1.333 + 1.334 + /* Nv3DVUtils instance */ 1.335 + nsAutoPtr<Nv3DVUtils> mNv3DVUtils; 1.336 + 1.337 + /** 1.338 + * Verifies all required device capabilities are present. 1.339 + */ 1.340 + bool VerifyCaps(); 1.341 +}; 1.342 + 1.343 +} /* namespace layers */ 1.344 +} /* namespace mozilla */ 1.345 + 1.346 +#endif /* GFX_DEVICEMANAGERD3D9_H */