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_LAYERMANAGERD3D9_H michael@0: #define GFX_LAYERMANAGERD3D9_H michael@0: michael@0: #include "Layers.h" michael@0: michael@0: #include michael@0: #include michael@0: michael@0: #include "gfxContext.h" michael@0: #include "nsIWidget.h" michael@0: michael@0: #include "DeviceManagerD3D9.h" michael@0: michael@0: namespace mozilla { michael@0: namespace layers { michael@0: michael@0: class LayerD3D9; michael@0: class ThebesLayerD3D9; michael@0: michael@0: /* michael@0: * This is the LayerManager used for Direct3D 9. For now this will render on michael@0: * the main thread. michael@0: */ michael@0: class LayerManagerD3D9 : public LayerManager { michael@0: public: michael@0: LayerManagerD3D9(nsIWidget *aWidget); michael@0: virtual ~LayerManagerD3D9(); michael@0: michael@0: /* michael@0: * Initializes the layer manager, this is when the layer manager will michael@0: * actually access the device and attempt to create the swap chain used michael@0: * to draw to the window. If this method fails the device cannot be used. michael@0: * This function is not threadsafe. michael@0: * michael@0: * \return True is initialization was succesful, false when it was not. michael@0: */ michael@0: bool Initialize(bool force = false); michael@0: michael@0: /* michael@0: * Sets the clipping region for this layer manager. This is important on michael@0: * windows because using OGL we no longer have GDI's native clipping. Therefor michael@0: * widget must tell us what part of the screen is being invalidated, michael@0: * and we should clip to this. michael@0: * michael@0: * \param aClippingRegion Region to clip to. Setting an empty region michael@0: * will disable clipping. michael@0: */ michael@0: void SetClippingRegion(const nsIntRegion& aClippingRegion); michael@0: michael@0: /* michael@0: * LayerManager implementation. michael@0: */ michael@0: virtual void Destroy(); michael@0: michael@0: virtual void BeginTransaction(); michael@0: michael@0: virtual void BeginTransactionWithTarget(gfxContext* aTarget); michael@0: michael@0: void EndConstruction(); michael@0: michael@0: virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT); michael@0: michael@0: struct CallbackInfo { michael@0: DrawThebesLayerCallback Callback; michael@0: void *CallbackData; michael@0: }; michael@0: michael@0: virtual void EndTransaction(DrawThebesLayerCallback aCallback, michael@0: void* aCallbackData, michael@0: EndTransactionFlags aFlags = END_DEFAULT); michael@0: michael@0: const CallbackInfo &GetCallbackInfo() { return mCurrentCallbackInfo; } michael@0: michael@0: void SetRoot(Layer* aLayer); michael@0: michael@0: virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) michael@0: { michael@0: if (!mDeviceManager) michael@0: return false; michael@0: int32_t maxSize = mDeviceManager->GetMaxTextureSize(); michael@0: return aSize <= gfx::IntSize(maxSize, maxSize); michael@0: } michael@0: michael@0: virtual int32_t GetMaxTextureSize() const michael@0: { michael@0: return mDeviceManager->GetMaxTextureSize(); michael@0: } michael@0: michael@0: virtual already_AddRefed CreateThebesLayer(); michael@0: michael@0: virtual already_AddRefed CreateContainerLayer(); michael@0: michael@0: virtual already_AddRefed CreateImageLayer(); michael@0: michael@0: virtual already_AddRefed CreateColorLayer(); michael@0: michael@0: virtual already_AddRefed CreateCanvasLayer(); michael@0: michael@0: virtual already_AddRefed CreateReadbackLayer(); michael@0: michael@0: virtual LayersBackend GetBackendType() { return LayersBackend::LAYERS_D3D9; } michael@0: virtual void GetBackendName(nsAString& name) { name.AssignLiteral("Direct3D 9"); } michael@0: bool DeviceWasRemoved() { return deviceManager()->DeviceWasRemoved(); } michael@0: michael@0: /* michael@0: * Helper methods. michael@0: */ michael@0: void SetClippingEnabled(bool aEnabled); michael@0: michael@0: void SetShaderMode(DeviceManagerD3D9::ShaderMode aMode, michael@0: Layer* aMask, bool aIs2D = true) michael@0: { mDeviceManager->SetShaderMode(aMode, aMask, aIs2D); } michael@0: michael@0: IDirect3DDevice9 *device() const { return mDeviceManager->device(); } michael@0: DeviceManagerD3D9 *deviceManager() const { return mDeviceManager; } michael@0: michael@0: /** michael@0: * Return pointer to the Nv3DVUtils instance. Re-direct to mDeviceManager. michael@0: */ michael@0: Nv3DVUtils *GetNv3DVUtils() { return mDeviceManager ? mDeviceManager->GetNv3DVUtils() : nullptr; } michael@0: michael@0: virtual const char* Name() const { return "D3D9"; } michael@0: michael@0: void ReportFailure(const nsACString &aMsg, HRESULT aCode); michael@0: michael@0: bool CompositingDisabled() { return mCompositingDisabled; } michael@0: void SetCompositingDisabled(bool aCompositingDisabled) { mCompositingDisabled = aCompositingDisabled; } michael@0: michael@0: private: michael@0: /* Device manager instance for this layer manager */ michael@0: nsRefPtr mDeviceManager; michael@0: michael@0: /* Swap chain associated with this layer manager */ michael@0: nsRefPtr mSwapChain; michael@0: michael@0: /* Widget associated with this layer manager */ michael@0: nsIWidget *mWidget; michael@0: michael@0: /* michael@0: * Context target, nullptr when drawing directly to our swap chain. michael@0: */ michael@0: nsRefPtr mTarget; michael@0: michael@0: /* Callback info for current transaction */ michael@0: CallbackInfo mCurrentCallbackInfo; michael@0: michael@0: /* michael@0: * Region we're clipping our current drawing to. michael@0: */ michael@0: nsIntRegion mClippingRegion; michael@0: michael@0: /* michael@0: * Device reset count at last paint. Whenever this changes, we need to michael@0: * do a full layer tree update. michael@0: */ michael@0: uint32_t mDeviceResetCount; michael@0: michael@0: /* michael@0: * True if we should only be drawing layer contents, not michael@0: * compositing them to the target. michael@0: */ michael@0: bool mCompositingDisabled; michael@0: michael@0: /* michael@0: * Render the current layer tree to the active target. michael@0: */ michael@0: void Render(); michael@0: michael@0: /* michael@0: * Setup the pipeline. michael@0: */ michael@0: void SetupPipeline(); michael@0: michael@0: /* michael@0: * Copies the content of our backbuffer to the set transaction target. michael@0: */ michael@0: void PaintToTarget(); michael@0: michael@0: }; michael@0: michael@0: /* michael@0: * General information and tree management for OGL layers. michael@0: */ michael@0: class LayerD3D9 michael@0: { michael@0: public: michael@0: LayerD3D9(LayerManagerD3D9 *aManager); michael@0: michael@0: virtual LayerD3D9 *GetFirstChildD3D9() { return nullptr; } michael@0: michael@0: void SetFirstChild(LayerD3D9 *aParent); michael@0: michael@0: virtual Layer* GetLayer() = 0; michael@0: michael@0: virtual void RenderLayer() = 0; michael@0: michael@0: /** michael@0: /* This function may be used on device resets to clear all VRAM resources michael@0: * that a layer might be using. michael@0: */ michael@0: virtual void CleanResources() {} michael@0: michael@0: IDirect3DDevice9 *device() const { return mD3DManager->device(); } michael@0: michael@0: /* Called by the layer manager when it's destroyed */ michael@0: virtual void LayerManagerDestroyed() {} michael@0: michael@0: void ReportFailure(const nsACString &aMsg, HRESULT aCode) { michael@0: return mD3DManager->ReportFailure(aMsg, aCode); michael@0: } michael@0: michael@0: void SetShaderTransformAndOpacity() michael@0: { michael@0: Layer* layer = GetLayer(); michael@0: const gfx::Matrix4x4& transform = layer->GetEffectiveTransform(); michael@0: device()->SetVertexShaderConstantF(CBmLayerTransform, &transform._11, 4); michael@0: michael@0: float opacity[4]; michael@0: /* michael@0: * We always upload a 4 component float, but the shader will use only the michael@0: * first component since it's declared as a 'float'. michael@0: */ michael@0: opacity[0] = layer->GetEffectiveOpacity(); michael@0: device()->SetPixelShaderConstantF(CBfLayerOpacity, opacity, 1); michael@0: } michael@0: michael@0: /* michael@0: * Returns a texture containing the contents of this michael@0: * layer. Will try to return an existing texture if possible, or a temporary michael@0: * one if not. It is the callee's responsibility to release the shader michael@0: * resource view. Will return null if a texture could not be constructed. michael@0: * The texture will not be transformed, i.e., it will be in the same coord michael@0: * space as this. michael@0: * Any layer that can be used as a mask layer should override this method. michael@0: * If aSize is non-null and a texture is successfully returned, aSize will michael@0: * contain the size of the texture. michael@0: */ michael@0: virtual already_AddRefed GetAsTexture(gfx::IntSize* aSize) michael@0: { michael@0: return nullptr; michael@0: } michael@0: michael@0: protected: michael@0: LayerManagerD3D9 *mD3DManager; michael@0: }; michael@0: michael@0: /* michael@0: * RAII helper for locking D3D9 textures. michael@0: */ michael@0: class LockTextureRectD3D9 michael@0: { michael@0: public: michael@0: LockTextureRectD3D9(IDirect3DTexture9* aTexture) michael@0: : mTexture(aTexture) michael@0: { michael@0: mLockResult = mTexture->LockRect(0, &mR, nullptr, 0); michael@0: } michael@0: michael@0: ~LockTextureRectD3D9() michael@0: { michael@0: mTexture->UnlockRect(0); michael@0: } michael@0: michael@0: bool HasLock() { michael@0: return SUCCEEDED(mLockResult); michael@0: } michael@0: michael@0: D3DLOCKED_RECT GetLockRect() michael@0: { michael@0: return mR; michael@0: } michael@0: private: michael@0: LockTextureRectD3D9 (const LockTextureRectD3D9&); michael@0: LockTextureRectD3D9& operator= (const LockTextureRectD3D9&); michael@0: michael@0: IDirect3DTexture9* mTexture; michael@0: D3DLOCKED_RECT mR; michael@0: HRESULT mLockResult; michael@0: }; michael@0: michael@0: } /* layers */ michael@0: } /* mozilla */ michael@0: michael@0: #endif /* GFX_LAYERMANAGERD3D9_H */