1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/d3d9/LayerManagerD3D9.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,289 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef GFX_LAYERMANAGERD3D9_H 1.10 +#define GFX_LAYERMANAGERD3D9_H 1.11 + 1.12 +#include "Layers.h" 1.13 + 1.14 +#include <windows.h> 1.15 +#include <d3d9.h> 1.16 + 1.17 +#include "gfxContext.h" 1.18 +#include "nsIWidget.h" 1.19 + 1.20 +#include "DeviceManagerD3D9.h" 1.21 + 1.22 +namespace mozilla { 1.23 +namespace layers { 1.24 + 1.25 +class LayerD3D9; 1.26 +class ThebesLayerD3D9; 1.27 + 1.28 +/* 1.29 + * This is the LayerManager used for Direct3D 9. For now this will render on 1.30 + * the main thread. 1.31 + */ 1.32 +class LayerManagerD3D9 : public LayerManager { 1.33 +public: 1.34 + LayerManagerD3D9(nsIWidget *aWidget); 1.35 + virtual ~LayerManagerD3D9(); 1.36 + 1.37 + /* 1.38 + * Initializes the layer manager, this is when the layer manager will 1.39 + * actually access the device and attempt to create the swap chain used 1.40 + * to draw to the window. If this method fails the device cannot be used. 1.41 + * This function is not threadsafe. 1.42 + * 1.43 + * \return True is initialization was succesful, false when it was not. 1.44 + */ 1.45 + bool Initialize(bool force = false); 1.46 + 1.47 + /* 1.48 + * Sets the clipping region for this layer manager. This is important on 1.49 + * windows because using OGL we no longer have GDI's native clipping. Therefor 1.50 + * widget must tell us what part of the screen is being invalidated, 1.51 + * and we should clip to this. 1.52 + * 1.53 + * \param aClippingRegion Region to clip to. Setting an empty region 1.54 + * will disable clipping. 1.55 + */ 1.56 + void SetClippingRegion(const nsIntRegion& aClippingRegion); 1.57 + 1.58 + /* 1.59 + * LayerManager implementation. 1.60 + */ 1.61 + virtual void Destroy(); 1.62 + 1.63 + virtual void BeginTransaction(); 1.64 + 1.65 + virtual void BeginTransactionWithTarget(gfxContext* aTarget); 1.66 + 1.67 + void EndConstruction(); 1.68 + 1.69 + virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT); 1.70 + 1.71 + struct CallbackInfo { 1.72 + DrawThebesLayerCallback Callback; 1.73 + void *CallbackData; 1.74 + }; 1.75 + 1.76 + virtual void EndTransaction(DrawThebesLayerCallback aCallback, 1.77 + void* aCallbackData, 1.78 + EndTransactionFlags aFlags = END_DEFAULT); 1.79 + 1.80 + const CallbackInfo &GetCallbackInfo() { return mCurrentCallbackInfo; } 1.81 + 1.82 + void SetRoot(Layer* aLayer); 1.83 + 1.84 + virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) 1.85 + { 1.86 + if (!mDeviceManager) 1.87 + return false; 1.88 + int32_t maxSize = mDeviceManager->GetMaxTextureSize(); 1.89 + return aSize <= gfx::IntSize(maxSize, maxSize); 1.90 + } 1.91 + 1.92 + virtual int32_t GetMaxTextureSize() const 1.93 + { 1.94 + return mDeviceManager->GetMaxTextureSize(); 1.95 + } 1.96 + 1.97 + virtual already_AddRefed<ThebesLayer> CreateThebesLayer(); 1.98 + 1.99 + virtual already_AddRefed<ContainerLayer> CreateContainerLayer(); 1.100 + 1.101 + virtual already_AddRefed<ImageLayer> CreateImageLayer(); 1.102 + 1.103 + virtual already_AddRefed<ColorLayer> CreateColorLayer(); 1.104 + 1.105 + virtual already_AddRefed<CanvasLayer> CreateCanvasLayer(); 1.106 + 1.107 + virtual already_AddRefed<ReadbackLayer> CreateReadbackLayer(); 1.108 + 1.109 + virtual LayersBackend GetBackendType() { return LayersBackend::LAYERS_D3D9; } 1.110 + virtual void GetBackendName(nsAString& name) { name.AssignLiteral("Direct3D 9"); } 1.111 + bool DeviceWasRemoved() { return deviceManager()->DeviceWasRemoved(); } 1.112 + 1.113 + /* 1.114 + * Helper methods. 1.115 + */ 1.116 + void SetClippingEnabled(bool aEnabled); 1.117 + 1.118 + void SetShaderMode(DeviceManagerD3D9::ShaderMode aMode, 1.119 + Layer* aMask, bool aIs2D = true) 1.120 + { mDeviceManager->SetShaderMode(aMode, aMask, aIs2D); } 1.121 + 1.122 + IDirect3DDevice9 *device() const { return mDeviceManager->device(); } 1.123 + DeviceManagerD3D9 *deviceManager() const { return mDeviceManager; } 1.124 + 1.125 + /** 1.126 + * Return pointer to the Nv3DVUtils instance. Re-direct to mDeviceManager. 1.127 + */ 1.128 + Nv3DVUtils *GetNv3DVUtils() { return mDeviceManager ? mDeviceManager->GetNv3DVUtils() : nullptr; } 1.129 + 1.130 + virtual const char* Name() const { return "D3D9"; } 1.131 + 1.132 + void ReportFailure(const nsACString &aMsg, HRESULT aCode); 1.133 + 1.134 + bool CompositingDisabled() { return mCompositingDisabled; } 1.135 + void SetCompositingDisabled(bool aCompositingDisabled) { mCompositingDisabled = aCompositingDisabled; } 1.136 + 1.137 +private: 1.138 + /* Device manager instance for this layer manager */ 1.139 + nsRefPtr<DeviceManagerD3D9> mDeviceManager; 1.140 + 1.141 + /* Swap chain associated with this layer manager */ 1.142 + nsRefPtr<SwapChainD3D9> mSwapChain; 1.143 + 1.144 + /* Widget associated with this layer manager */ 1.145 + nsIWidget *mWidget; 1.146 + 1.147 + /* 1.148 + * Context target, nullptr when drawing directly to our swap chain. 1.149 + */ 1.150 + nsRefPtr<gfxContext> mTarget; 1.151 + 1.152 + /* Callback info for current transaction */ 1.153 + CallbackInfo mCurrentCallbackInfo; 1.154 + 1.155 + /* 1.156 + * Region we're clipping our current drawing to. 1.157 + */ 1.158 + nsIntRegion mClippingRegion; 1.159 + 1.160 + /* 1.161 + * Device reset count at last paint. Whenever this changes, we need to 1.162 + * do a full layer tree update. 1.163 + */ 1.164 + uint32_t mDeviceResetCount; 1.165 + 1.166 + /* 1.167 + * True if we should only be drawing layer contents, not 1.168 + * compositing them to the target. 1.169 + */ 1.170 + bool mCompositingDisabled; 1.171 + 1.172 + /* 1.173 + * Render the current layer tree to the active target. 1.174 + */ 1.175 + void Render(); 1.176 + 1.177 + /* 1.178 + * Setup the pipeline. 1.179 + */ 1.180 + void SetupPipeline(); 1.181 + 1.182 + /* 1.183 + * Copies the content of our backbuffer to the set transaction target. 1.184 + */ 1.185 + void PaintToTarget(); 1.186 + 1.187 +}; 1.188 + 1.189 +/* 1.190 + * General information and tree management for OGL layers. 1.191 + */ 1.192 +class LayerD3D9 1.193 +{ 1.194 +public: 1.195 + LayerD3D9(LayerManagerD3D9 *aManager); 1.196 + 1.197 + virtual LayerD3D9 *GetFirstChildD3D9() { return nullptr; } 1.198 + 1.199 + void SetFirstChild(LayerD3D9 *aParent); 1.200 + 1.201 + virtual Layer* GetLayer() = 0; 1.202 + 1.203 + virtual void RenderLayer() = 0; 1.204 + 1.205 + /** 1.206 + /* This function may be used on device resets to clear all VRAM resources 1.207 + * that a layer might be using. 1.208 + */ 1.209 + virtual void CleanResources() {} 1.210 + 1.211 + IDirect3DDevice9 *device() const { return mD3DManager->device(); } 1.212 + 1.213 + /* Called by the layer manager when it's destroyed */ 1.214 + virtual void LayerManagerDestroyed() {} 1.215 + 1.216 + void ReportFailure(const nsACString &aMsg, HRESULT aCode) { 1.217 + return mD3DManager->ReportFailure(aMsg, aCode); 1.218 + } 1.219 + 1.220 + void SetShaderTransformAndOpacity() 1.221 + { 1.222 + Layer* layer = GetLayer(); 1.223 + const gfx::Matrix4x4& transform = layer->GetEffectiveTransform(); 1.224 + device()->SetVertexShaderConstantF(CBmLayerTransform, &transform._11, 4); 1.225 + 1.226 + float opacity[4]; 1.227 + /* 1.228 + * We always upload a 4 component float, but the shader will use only the 1.229 + * first component since it's declared as a 'float'. 1.230 + */ 1.231 + opacity[0] = layer->GetEffectiveOpacity(); 1.232 + device()->SetPixelShaderConstantF(CBfLayerOpacity, opacity, 1); 1.233 + } 1.234 + 1.235 + /* 1.236 + * Returns a texture containing the contents of this 1.237 + * layer. Will try to return an existing texture if possible, or a temporary 1.238 + * one if not. It is the callee's responsibility to release the shader 1.239 + * resource view. Will return null if a texture could not be constructed. 1.240 + * The texture will not be transformed, i.e., it will be in the same coord 1.241 + * space as this. 1.242 + * Any layer that can be used as a mask layer should override this method. 1.243 + * If aSize is non-null and a texture is successfully returned, aSize will 1.244 + * contain the size of the texture. 1.245 + */ 1.246 + virtual already_AddRefed<IDirect3DTexture9> GetAsTexture(gfx::IntSize* aSize) 1.247 + { 1.248 + return nullptr; 1.249 + } 1.250 + 1.251 +protected: 1.252 + LayerManagerD3D9 *mD3DManager; 1.253 +}; 1.254 + 1.255 +/* 1.256 + * RAII helper for locking D3D9 textures. 1.257 + */ 1.258 +class LockTextureRectD3D9 1.259 +{ 1.260 +public: 1.261 + LockTextureRectD3D9(IDirect3DTexture9* aTexture) 1.262 + : mTexture(aTexture) 1.263 + { 1.264 + mLockResult = mTexture->LockRect(0, &mR, nullptr, 0); 1.265 + } 1.266 + 1.267 + ~LockTextureRectD3D9() 1.268 + { 1.269 + mTexture->UnlockRect(0); 1.270 + } 1.271 + 1.272 + bool HasLock() { 1.273 + return SUCCEEDED(mLockResult); 1.274 + } 1.275 + 1.276 + D3DLOCKED_RECT GetLockRect() 1.277 + { 1.278 + return mR; 1.279 + } 1.280 +private: 1.281 + LockTextureRectD3D9 (const LockTextureRectD3D9&); 1.282 + LockTextureRectD3D9& operator= (const LockTextureRectD3D9&); 1.283 + 1.284 + IDirect3DTexture9* mTexture; 1.285 + D3DLOCKED_RECT mR; 1.286 + HRESULT mLockResult; 1.287 +}; 1.288 + 1.289 +} /* layers */ 1.290 +} /* mozilla */ 1.291 + 1.292 +#endif /* GFX_LAYERMANAGERD3D9_H */