summaryrefslogtreecommitdiffstats
path: root/gfx/layers/d3d9/DeviceManagerD3D9.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/layers/d3d9/DeviceManagerD3D9.h')
-rw-r--r--gfx/layers/d3d9/DeviceManagerD3D9.h353
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 */