mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-31 14:15:30 +00:00
342 lines
10 KiB
C++
342 lines
10 KiB
C++
/* -*- 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"
|
|
|
|
struct nsIntRect;
|
|
|
|
namespace mozilla {
|
|
namespace layers {
|
|
|
|
class DeviceManagerD3D9;
|
|
class LayerD3D9;
|
|
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;
|
|
|
|
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
|
|
{
|
|
NS_INLINE_DECL_REFCOUNTING(SwapChainD3D9)
|
|
public:
|
|
~SwapChainD3D9();
|
|
|
|
/**
|
|
* 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 nsIntRect &aRect);
|
|
void Present();
|
|
|
|
private:
|
|
friend class DeviceManagerD3D9;
|
|
|
|
SwapChainD3D9(DeviceManagerD3D9 *aDeviceManager);
|
|
|
|
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();
|
|
|
|
nsRefPtr<IDirect3DSwapChain9> mSwapChain;
|
|
nsRefPtr<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 MOZ_FINAL
|
|
{
|
|
public:
|
|
DeviceManagerD3D9();
|
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(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 Init();
|
|
|
|
/**
|
|
* 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 HasDynamicTextures() { return mHasDynamicTextures; }
|
|
|
|
enum ShaderMode {
|
|
RGBLAYER,
|
|
RGBALAYER,
|
|
COMPONENTLAYERPASS1,
|
|
COMPONENTLAYERPASS2,
|
|
YCBCRLAYER,
|
|
SOLIDCOLORLAYER
|
|
};
|
|
|
|
void SetShaderMode(ShaderMode aMode, Layer* aMask, bool aIs2D);
|
|
// 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; }
|
|
|
|
/**
|
|
* We keep a list of all layers here that may have hardware resource allocated
|
|
* so we can clean their resources on reset.
|
|
*/
|
|
nsTArray<LayerD3D9*> mLayersWithResources;
|
|
|
|
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.
|
|
*/
|
|
TemporaryRef<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();
|
|
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 */
|
|
nsRefPtr<IDirect3DDevice9> mDevice;
|
|
|
|
/* The D3D9Ex device - only valid on Vista+ with WDDM */
|
|
nsRefPtr<IDirect3DDevice9Ex> mDeviceEx;
|
|
|
|
/* An instance of the D3D9 object */
|
|
nsRefPtr<IDirect3D9> mD3D9;
|
|
|
|
/* An instance of the D3D9Ex object - only valid on Vista+ with WDDM */
|
|
nsRefPtr<IDirect3D9Ex> mD3D9Ex;
|
|
|
|
/* Vertex shader used for layer quads */
|
|
nsRefPtr<IDirect3DVertexShader9> mLayerVS;
|
|
|
|
/* Pixel shader used for RGB textures */
|
|
nsRefPtr<IDirect3DPixelShader9> mRGBPS;
|
|
|
|
/* Pixel shader used for RGBA textures */
|
|
nsRefPtr<IDirect3DPixelShader9> mRGBAPS;
|
|
|
|
/* Pixel shader used for component alpha textures (pass 1) */
|
|
nsRefPtr<IDirect3DPixelShader9> mComponentPass1PS;
|
|
|
|
/* Pixel shader used for component alpha textures (pass 2) */
|
|
nsRefPtr<IDirect3DPixelShader9> mComponentPass2PS;
|
|
|
|
/* Pixel shader used for RGB textures */
|
|
nsRefPtr<IDirect3DPixelShader9> mYCbCrPS;
|
|
|
|
/* Pixel shader used for solid colors */
|
|
nsRefPtr<IDirect3DPixelShader9> mSolidColorPS;
|
|
|
|
/* As above, but using a mask layer */
|
|
nsRefPtr<IDirect3DVertexShader9> mLayerVSMask;
|
|
nsRefPtr<IDirect3DVertexShader9> mLayerVSMask3D;
|
|
nsRefPtr<IDirect3DPixelShader9> mRGBPSMask;
|
|
nsRefPtr<IDirect3DPixelShader9> mRGBAPSMask;
|
|
nsRefPtr<IDirect3DPixelShader9> mRGBAPSMask3D;
|
|
nsRefPtr<IDirect3DPixelShader9> mComponentPass1PSMask;
|
|
nsRefPtr<IDirect3DPixelShader9> mComponentPass2PSMask;
|
|
nsRefPtr<IDirect3DPixelShader9> mYCbCrPSMask;
|
|
nsRefPtr<IDirect3DPixelShader9> mSolidColorPSMask;
|
|
|
|
/* Vertex buffer containing our basic vertex structure */
|
|
nsRefPtr<IDirect3DVertexBuffer9> mVB;
|
|
|
|
/* Our vertex declaration */
|
|
nsRefPtr<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 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 */
|