diff options
Diffstat (limited to 'gfx/layers/d3d9/DeviceManagerD3D9.h')
-rw-r--r-- | gfx/layers/d3d9/DeviceManagerD3D9.h | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/gfx/layers/d3d9/DeviceManagerD3D9.h b/gfx/layers/d3d9/DeviceManagerD3D9.h new file mode 100644 index 000000000..d27b679ab --- /dev/null +++ b/gfx/layers/d3d9/DeviceManagerD3D9.h @@ -0,0 +1,353 @@ +/* -*- 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 GFX_DEVICEMANAGERD3D9_H +#define GFX_DEVICEMANAGERD3D9_H + +#include "gfxTypes.h" +#include "nsAutoPtr.h" +#include "d3d9.h" +#include "nsTArray.h" +#include "mozilla/layers/CompositorTypes.h" +#include "mozilla/RefPtr.h" +#include "mozilla/gfx/Rect.h" + +namespace mozilla { +namespace layers { + +class DeviceManagerD3D9; +class Nv3DVUtils; +class Layer; +class TextureSourceD3D9; + +// Shader Constant locations +const int CBmLayerTransform = 0; +const int CBmProjection = 4; +const int CBvRenderTargetOffset = 8; +const int CBvTextureCoords = 9; +const int CBvLayerQuad = 10; +// we don't use opacity with solid color shaders +const int CBfLayerOpacity = 0; +const int CBvColor = 0; +const int CBmYuvColorMatrix = 1; + +enum DeviceManagerState { + // The device and swap chain are OK. + DeviceOK, + // The device or swap chain are in a bad state, and we should not render. + DeviceFail, + // The device is lost and cannot be reset, the user should forget the + // current device manager and create a new one. + DeviceMustRecreate, +}; + + +/** + * This structure is used to pass rectangles to our shader constant. We can use + * this for passing rectangular areas to SetVertexShaderConstant. In the format + * of a 4 component float(x,y,width,height). Our vertex shader can then use + * this to construct rectangular positions from the 0,0-1,1 quad that we source + * it with. + */ +struct ShaderConstantRect +{ + float mX, mY, mWidth, mHeight; + + // Provide all the commonly used argument types to prevent all the local + // casts in the code. + ShaderConstantRect(float aX, float aY, float aWidth, float aHeight) + : mX(aX), mY(aY), mWidth(aWidth), mHeight(aHeight) + { } + + ShaderConstantRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight) + : mX((float)aX), mY((float)aY) + , mWidth((float)aWidth), mHeight((float)aHeight) + { } + + ShaderConstantRect(int32_t aX, int32_t aY, float aWidth, float aHeight) + : mX((float)aX), mY((float)aY), mWidth(aWidth), mHeight(aHeight) + { } + + // For easy passing to SetVertexShaderConstantF. + operator float* () { return &mX; } +}; + +/** + * SwapChain class, this class manages the swap chain belonging to a + * LayerManagerD3D9. + */ +class SwapChainD3D9 final +{ + NS_INLINE_DECL_REFCOUNTING(SwapChainD3D9) +public: + + /** + * This function will prepare the device this swap chain belongs to for + * rendering to this swap chain. Only after calling this function can the + * swap chain be drawn to, and only until this function is called on another + * swap chain belonging to this device will the device draw to it. Passed in + * is the size of the swap chain. If the window size differs from the size + * during the last call to this function the swap chain will resize. Note that + * in no case does this function guarantee the backbuffer to still have its + * old content. + */ + DeviceManagerState PrepareForRendering(); + + already_AddRefed<IDirect3DSurface9> GetBackBuffer(); + + /** + * This function will present the selected rectangle of the swap chain to + * its associated window. + */ + void Present(const gfx::IntRect &aRect); + void Present(); + +private: + friend class DeviceManagerD3D9; + + SwapChainD3D9(DeviceManagerD3D9 *aDeviceManager); + + // Private destructor, to discourage deletion outside of Release(): + ~SwapChainD3D9(); + + bool Init(HWND hWnd); + + /** + * This causes us to release our swap chain, clearing out our resource usage + * so the master device may reset. + */ + void Reset(); + + RefPtr<IDirect3DSwapChain9> mSwapChain; + RefPtr<DeviceManagerD3D9> mDeviceManager; + HWND mWnd; +}; + +/** + * Device manager, this class is used by the layer managers to share the D3D9 + * device and create swap chains for the individual windows the layer managers + * belong to. + */ +class DeviceManagerD3D9 final +{ +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DeviceManagerD3D9) + + /** + * Setup or tear down static resources needed for D3D9. + */ + static void Init(); + static void Shutdown(); + + /** + * Static accessors and helpers for accessing the global DeviceManagerD3D9 + * instance. + */ + static RefPtr<DeviceManagerD3D9> Get(); + static RefPtr<IDirect3DDevice9> GetDevice(); + static void OnDeviceManagerDestroy(DeviceManagerD3D9* aDeviceManager); + + /** + * Sets up the render state for the device for layer rendering. + */ + void SetupRenderState(); + + /** + * Create a swap chain setup to work with the specified window. + */ + already_AddRefed<SwapChainD3D9> CreateSwapChain(HWND hWnd); + + IDirect3DDevice9 *device() { return mDevice; } + + bool IsD3D9Ex() { return mDeviceEx; } + + bool HasComponentAlpha() { return mHasComponentAlpha; } + + bool HasDynamicTextures() { return mHasDynamicTextures; } + + enum ShaderMode { + RGBLAYER, + RGBALAYER, + COMPONENTLAYERPASS1, + COMPONENTLAYERPASS2, + YCBCRLAYER, + SOLIDCOLORLAYER + }; + + // returns the register to be used for the mask texture, if appropriate + uint32_t SetShaderMode(ShaderMode aMode, MaskType aMaskType); + + /** + * Return pointer to the Nv3DVUtils instance + */ + Nv3DVUtils *GetNv3DVUtils() { return mNv3DVUtils; } + + /** + * Returns true if this device was removed. + */ + bool DeviceWasRemoved() { return mDeviceWasRemoved; } + + uint32_t GetDeviceResetCount() { return mDeviceResetCount; } + + int32_t GetMaxTextureSize() { return mMaxTextureSize; } + + // Removes aHost from our list of texture hosts if it is the head. + void RemoveTextureListHead(TextureSourceD3D9* aHost); + + /** + * Creates a texture using our device. + * If needed, we keep a record of the new texture, so the texture can be + * released. In this case, aTextureHostIDirect3DTexture9 must be non-null. + */ + already_AddRefed<IDirect3DTexture9> CreateTexture(const gfx::IntSize &aSize, + _D3DFORMAT aFormat, + D3DPOOL aPool, + TextureSourceD3D9* aTextureHostIDirect3DTexture9); +#ifdef DEBUG + // Looks for aFind in the list of texture hosts. + // O(n) so only use for assertions. + bool IsInTextureHostList(TextureSourceD3D9* aFind); +#endif + + /** + * This function verifies the device is ready for rendering, internally this + * will test the cooperative level of the device and reset the device if + * needed. If this returns false subsequent rendering calls may return errors. + */ + DeviceManagerState VerifyReadyForRendering(); + + static uint32_t sMaskQuadRegister; + +private: + friend class SwapChainD3D9; + + DeviceManagerD3D9(); + ~DeviceManagerD3D9(); + + /** + * Initialises the device manager, the underlying device, and everything else + * the manager needs. + * Returns true if initialisation succeeds, false otherwise. + * Note that if initisalisation fails, you cannot try again - you must throw + * away the DeviceManagerD3D9 and create a new one. + */ + bool Initialize(); + + void DestroyDevice(); + + /** + * This will fill our vertex buffer with the data of our quad, it may be + * called when the vertex buffer is recreated. + */ + bool CreateVertexBuffer(); + + /** + * Release all textures created by this device manager. + */ + void ReleaseTextureResources(); + /** + * Add aHost to our list of texture hosts. + */ + void RegisterTextureHost(TextureSourceD3D9* aHost); + + /* Array used to store all swap chains for device resets */ + nsTArray<SwapChainD3D9*> mSwapChains; + + /* The D3D device we use */ + RefPtr<IDirect3DDevice9> mDevice; + + /* The D3D9Ex device - only valid on Vista+ with WDDM */ + RefPtr<IDirect3DDevice9Ex> mDeviceEx; + + /* An instance of the D3D9 object */ + RefPtr<IDirect3D9> mD3D9; + + /* An instance of the D3D9Ex object - only valid on Vista+ with WDDM */ + RefPtr<IDirect3D9Ex> mD3D9Ex; + + /* Vertex shader used for layer quads */ + RefPtr<IDirect3DVertexShader9> mLayerVS; + + /* Pixel shader used for RGB textures */ + RefPtr<IDirect3DPixelShader9> mRGBPS; + + /* Pixel shader used for RGBA textures */ + RefPtr<IDirect3DPixelShader9> mRGBAPS; + + /* Pixel shader used for component alpha textures (pass 1) */ + RefPtr<IDirect3DPixelShader9> mComponentPass1PS; + + /* Pixel shader used for component alpha textures (pass 2) */ + RefPtr<IDirect3DPixelShader9> mComponentPass2PS; + + /* Pixel shader used for RGB textures */ + RefPtr<IDirect3DPixelShader9> mYCbCrPS; + + /* Pixel shader used for solid colors */ + RefPtr<IDirect3DPixelShader9> mSolidColorPS; + + /* As above, but using a mask layer */ + RefPtr<IDirect3DVertexShader9> mLayerVSMask; + RefPtr<IDirect3DPixelShader9> mRGBPSMask; + RefPtr<IDirect3DPixelShader9> mRGBAPSMask; + RefPtr<IDirect3DPixelShader9> mComponentPass1PSMask; + RefPtr<IDirect3DPixelShader9> mComponentPass2PSMask; + RefPtr<IDirect3DPixelShader9> mYCbCrPSMask; + RefPtr<IDirect3DPixelShader9> mSolidColorPSMask; + + /* Vertex buffer containing our basic vertex structure */ + RefPtr<IDirect3DVertexBuffer9> mVB; + + /* Our vertex declaration */ + RefPtr<IDirect3DVertexDeclaration9> mVD; + + /* We maintain a doubly linked list of all d3d9 texture hosts which host + * d3d9 textures created by this device manager. + * Texture hosts must remove themselves when they disappear (i.e., we + * expect all hosts in the list to be valid). + * The list is cleared when we release the textures. + */ + TextureSourceD3D9* mTextureHostList; + + /* Our focus window - this is really a dummy window we can associate our + * device with. + */ + HWND mFocusWnd; + + /* we use this to help track if our device temporarily or permanently lost */ + HMONITOR mDeviceMonitor; + + uint32_t mDeviceResetCount; + + uint32_t mMaxTextureSize; + + /** + * Wrap (repeat) or clamp textures. We prefer the former so we can do buffer + * rotation, but some older hardware doesn't support it. + */ + D3DTEXTUREADDRESS mTextureAddressingMode; + + /* If this device supports component alpha */ + bool mHasComponentAlpha; + + /* If this device supports dynamic textures */ + bool mHasDynamicTextures; + + /* If this device was removed */ + bool mDeviceWasRemoved; + + /* Nv3DVUtils instance */ + nsAutoPtr<Nv3DVUtils> mNv3DVUtils; + + /** + * Verifies all required device capabilities are present. + */ + bool VerifyCaps(); +}; + +} /* namespace layers */ +} /* namespace mozilla */ + +#endif /* GFX_DEVICEMANAGERD3D9_H */ |