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