Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
michael@0 | 2 | * This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #ifndef GFX_LAYERMANAGERD3D10_H |
michael@0 | 7 | #define GFX_LAYERMANAGERD3D10_H |
michael@0 | 8 | |
michael@0 | 9 | #include "Layers.h" |
michael@0 | 10 | |
michael@0 | 11 | #include <windows.h> |
michael@0 | 12 | #include <d3d10_1.h> |
michael@0 | 13 | |
michael@0 | 14 | #include "gfxContext.h" |
michael@0 | 15 | #include "mozilla/gfx/UserData.h" |
michael@0 | 16 | #include "nsIWidget.h" |
michael@0 | 17 | |
michael@0 | 18 | #include "ReadbackManagerD3D10.h" |
michael@0 | 19 | |
michael@0 | 20 | namespace mozilla { |
michael@0 | 21 | namespace layers { |
michael@0 | 22 | |
michael@0 | 23 | class DummyRoot; |
michael@0 | 24 | class Nv3DVUtils; |
michael@0 | 25 | |
michael@0 | 26 | /** |
michael@0 | 27 | * This structure is used to pass rectangles to our shader constant. We can use |
michael@0 | 28 | * this for passing rectangular areas to SetVertexShaderConstant. In the format |
michael@0 | 29 | * of a 4 component float(x,y,width,height). Our vertex shader can then use |
michael@0 | 30 | * this to construct rectangular positions from the 0,0-1,1 quad that we source |
michael@0 | 31 | * it with. |
michael@0 | 32 | */ |
michael@0 | 33 | struct ShaderConstantRectD3D10 |
michael@0 | 34 | { |
michael@0 | 35 | float mX, mY, mWidth, mHeight; |
michael@0 | 36 | ShaderConstantRectD3D10(float aX, float aY, float aWidth, float aHeight) |
michael@0 | 37 | : mX(aX), mY(aY), mWidth(aWidth), mHeight(aHeight) |
michael@0 | 38 | { } |
michael@0 | 39 | |
michael@0 | 40 | // For easy passing to SetVertexShaderConstantF. |
michael@0 | 41 | operator float* () { return &mX; } |
michael@0 | 42 | }; |
michael@0 | 43 | |
michael@0 | 44 | /* |
michael@0 | 45 | * This is the LayerManager used for Direct3D 10. For now this will |
michael@0 | 46 | * render on the main thread. |
michael@0 | 47 | * |
michael@0 | 48 | * For the time being, LayerManagerD3D10 forwards layers |
michael@0 | 49 | * transactions. |
michael@0 | 50 | */ |
michael@0 | 51 | class LayerManagerD3D10 : public LayerManager { |
michael@0 | 52 | typedef mozilla::gfx::DrawTarget DrawTarget; |
michael@0 | 53 | typedef mozilla::gfx::IntSize IntSize; |
michael@0 | 54 | typedef mozilla::gfx::SurfaceFormat SurfaceFormat; |
michael@0 | 55 | |
michael@0 | 56 | public: |
michael@0 | 57 | LayerManagerD3D10(nsIWidget *aWidget); |
michael@0 | 58 | virtual ~LayerManagerD3D10(); |
michael@0 | 59 | |
michael@0 | 60 | /* |
michael@0 | 61 | * Initializes the layer manager, this is when the layer manager will |
michael@0 | 62 | * actually access the device and attempt to create the swap chain used |
michael@0 | 63 | * to draw to the window. If this method fails the device cannot be used. |
michael@0 | 64 | * This function is not threadsafe. |
michael@0 | 65 | * |
michael@0 | 66 | * return True is initialization was succesful, false when it was not. |
michael@0 | 67 | */ |
michael@0 | 68 | bool Initialize(bool force = false, HRESULT* aHresultPtr = nullptr); |
michael@0 | 69 | |
michael@0 | 70 | /* |
michael@0 | 71 | * LayerManager implementation. |
michael@0 | 72 | */ |
michael@0 | 73 | virtual void Destroy(); |
michael@0 | 74 | |
michael@0 | 75 | virtual void SetRoot(Layer *aLayer); |
michael@0 | 76 | |
michael@0 | 77 | virtual void BeginTransaction(); |
michael@0 | 78 | |
michael@0 | 79 | virtual void BeginTransactionWithTarget(gfxContext* aTarget); |
michael@0 | 80 | |
michael@0 | 81 | virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT); |
michael@0 | 82 | |
michael@0 | 83 | struct CallbackInfo { |
michael@0 | 84 | DrawThebesLayerCallback Callback; |
michael@0 | 85 | void *CallbackData; |
michael@0 | 86 | }; |
michael@0 | 87 | |
michael@0 | 88 | virtual void EndTransaction(DrawThebesLayerCallback aCallback, |
michael@0 | 89 | void* aCallbackData, |
michael@0 | 90 | EndTransactionFlags aFlags = END_DEFAULT); |
michael@0 | 91 | |
michael@0 | 92 | const CallbackInfo &GetCallbackInfo() { return mCurrentCallbackInfo; } |
michael@0 | 93 | |
michael@0 | 94 | // D3D10 guarantees textures can be at least this size |
michael@0 | 95 | enum { |
michael@0 | 96 | MAX_TEXTURE_SIZE = 8192 |
michael@0 | 97 | }; |
michael@0 | 98 | virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) |
michael@0 | 99 | { |
michael@0 | 100 | return aSize <= gfx::IntSize(MAX_TEXTURE_SIZE, MAX_TEXTURE_SIZE); |
michael@0 | 101 | } |
michael@0 | 102 | |
michael@0 | 103 | virtual int32_t GetMaxTextureSize() const |
michael@0 | 104 | { |
michael@0 | 105 | return MAX_TEXTURE_SIZE; |
michael@0 | 106 | } |
michael@0 | 107 | |
michael@0 | 108 | virtual already_AddRefed<ThebesLayer> CreateThebesLayer(); |
michael@0 | 109 | virtual already_AddRefed<ContainerLayer> CreateContainerLayer(); |
michael@0 | 110 | virtual already_AddRefed<ImageLayer> CreateImageLayer(); |
michael@0 | 111 | virtual already_AddRefed<ColorLayer> CreateColorLayer(); |
michael@0 | 112 | virtual already_AddRefed<CanvasLayer> CreateCanvasLayer(); |
michael@0 | 113 | virtual already_AddRefed<ReadbackLayer> CreateReadbackLayer(); |
michael@0 | 114 | |
michael@0 | 115 | virtual TemporaryRef<DrawTarget> |
michael@0 | 116 | CreateOptimalDrawTarget(const IntSize &aSize, |
michael@0 | 117 | SurfaceFormat aSurfaceFormat); |
michael@0 | 118 | |
michael@0 | 119 | virtual TemporaryRef<DrawTarget> |
michael@0 | 120 | CreateOptimalMaskDrawTarget(const IntSize &aSize); |
michael@0 | 121 | |
michael@0 | 122 | virtual TemporaryRef<mozilla::gfx::DrawTarget> |
michael@0 | 123 | CreateDrawTarget(const gfx::IntSize &aSize, |
michael@0 | 124 | mozilla::gfx::SurfaceFormat aFormat); |
michael@0 | 125 | |
michael@0 | 126 | virtual LayersBackend GetBackendType() { return LayersBackend::LAYERS_D3D10; } |
michael@0 | 127 | virtual void GetBackendName(nsAString& name) { name.AssignLiteral("Direct3D 10"); } |
michael@0 | 128 | |
michael@0 | 129 | virtual const char* Name() const { return "D3D10"; } |
michael@0 | 130 | |
michael@0 | 131 | // Public helpers |
michael@0 | 132 | |
michael@0 | 133 | ID3D10Device1 *device() const { return mDevice; } |
michael@0 | 134 | |
michael@0 | 135 | ID3D10Effect *effect() const { return mEffect; } |
michael@0 | 136 | IDXGISwapChain *SwapChain() const |
michael@0 | 137 | { |
michael@0 | 138 | return mSwapChain; |
michael@0 | 139 | } |
michael@0 | 140 | ReadbackManagerD3D10 *readbackManager(); |
michael@0 | 141 | |
michael@0 | 142 | void SetupInputAssembler(); |
michael@0 | 143 | void SetViewport(const nsIntSize &aViewport); |
michael@0 | 144 | const nsIntSize &GetViewport() { return mViewport; } |
michael@0 | 145 | |
michael@0 | 146 | /** |
michael@0 | 147 | * Return pointer to the Nv3DVUtils instance |
michael@0 | 148 | */ |
michael@0 | 149 | Nv3DVUtils *GetNv3DVUtils() { return mNv3DVUtils; } |
michael@0 | 150 | |
michael@0 | 151 | static void ReportFailure(const nsACString &aMsg, HRESULT aCode); |
michael@0 | 152 | |
michael@0 | 153 | private: |
michael@0 | 154 | void SetupPipeline(); |
michael@0 | 155 | void UpdateRenderTarget(); |
michael@0 | 156 | void VerifyBufferSize(); |
michael@0 | 157 | void EnsureReadbackManager(); |
michael@0 | 158 | |
michael@0 | 159 | void Render(EndTransactionFlags aFlags); |
michael@0 | 160 | |
michael@0 | 161 | nsRefPtr<ID3D10Device1> mDevice; |
michael@0 | 162 | |
michael@0 | 163 | nsRefPtr<ID3D10Effect> mEffect; |
michael@0 | 164 | nsRefPtr<ID3D10InputLayout> mInputLayout; |
michael@0 | 165 | nsRefPtr<ID3D10Buffer> mVertexBuffer; |
michael@0 | 166 | nsRefPtr<ReadbackManagerD3D10> mReadbackManager; |
michael@0 | 167 | |
michael@0 | 168 | nsRefPtr<ID3D10RenderTargetView> mRTView; |
michael@0 | 169 | |
michael@0 | 170 | nsRefPtr<IDXGISwapChain> mSwapChain; |
michael@0 | 171 | |
michael@0 | 172 | nsIWidget *mWidget; |
michael@0 | 173 | |
michael@0 | 174 | bool mDisableSequenceForNextFrame; |
michael@0 | 175 | |
michael@0 | 176 | CallbackInfo mCurrentCallbackInfo; |
michael@0 | 177 | |
michael@0 | 178 | nsIntSize mViewport; |
michael@0 | 179 | |
michael@0 | 180 | /* Nv3DVUtils instance */ |
michael@0 | 181 | nsAutoPtr<Nv3DVUtils> mNv3DVUtils; |
michael@0 | 182 | |
michael@0 | 183 | /* |
michael@0 | 184 | * Context target, nullptr when drawing directly to our swap chain. |
michael@0 | 185 | */ |
michael@0 | 186 | nsRefPtr<gfxContext> mTarget; |
michael@0 | 187 | |
michael@0 | 188 | /* |
michael@0 | 189 | * Copies the content of our backbuffer to the set transaction target. |
michael@0 | 190 | */ |
michael@0 | 191 | void PaintToTarget(); |
michael@0 | 192 | }; |
michael@0 | 193 | |
michael@0 | 194 | /* |
michael@0 | 195 | * General information and tree management for OGL layers. |
michael@0 | 196 | */ |
michael@0 | 197 | class LayerD3D10 |
michael@0 | 198 | { |
michael@0 | 199 | public: |
michael@0 | 200 | LayerD3D10(LayerManagerD3D10 *aManager); |
michael@0 | 201 | |
michael@0 | 202 | virtual LayerD3D10 *GetFirstChildD3D10() { return nullptr; } |
michael@0 | 203 | |
michael@0 | 204 | void SetFirstChild(LayerD3D10 *aParent); |
michael@0 | 205 | |
michael@0 | 206 | virtual Layer* GetLayer() = 0; |
michael@0 | 207 | |
michael@0 | 208 | /** |
michael@0 | 209 | * This will render a child layer to whatever render target is currently |
michael@0 | 210 | * active. |
michael@0 | 211 | */ |
michael@0 | 212 | virtual void RenderLayer() = 0; |
michael@0 | 213 | virtual void Validate() {} |
michael@0 | 214 | |
michael@0 | 215 | ID3D10Device1 *device() const { return mD3DManager->device(); } |
michael@0 | 216 | ID3D10Effect *effect() const { return mD3DManager->effect(); } |
michael@0 | 217 | |
michael@0 | 218 | /* Called by the layer manager when it's destroyed */ |
michael@0 | 219 | virtual void LayerManagerDestroyed() {} |
michael@0 | 220 | |
michael@0 | 221 | /** |
michael@0 | 222 | * Return pointer to the Nv3DVUtils instance. Calls equivalent method in LayerManager. |
michael@0 | 223 | */ |
michael@0 | 224 | Nv3DVUtils *GetNv3DVUtils() { return mD3DManager->GetNv3DVUtils(); } |
michael@0 | 225 | |
michael@0 | 226 | /* |
michael@0 | 227 | * Returns a shader resource view of a texture containing the contents of this |
michael@0 | 228 | * layer. Will try to return an existing texture if possible, or a temporary |
michael@0 | 229 | * one if not. It is the callee's responsibility to release the shader |
michael@0 | 230 | * resource view. Will return null if a texture could not be constructed. |
michael@0 | 231 | * The texture will not be transformed, i.e., it will be in the same coord |
michael@0 | 232 | * space as this. |
michael@0 | 233 | * Any layer that can be used as a mask layer should override this method. |
michael@0 | 234 | * If aSize is non-null, it will contain the size of the texture. |
michael@0 | 235 | */ |
michael@0 | 236 | virtual already_AddRefed<ID3D10ShaderResourceView> GetAsTexture(gfx::IntSize* aSize) |
michael@0 | 237 | { |
michael@0 | 238 | return nullptr; |
michael@0 | 239 | } |
michael@0 | 240 | |
michael@0 | 241 | void SetEffectTransformAndOpacity() |
michael@0 | 242 | { |
michael@0 | 243 | Layer* layer = GetLayer(); |
michael@0 | 244 | const gfx::Matrix4x4& transform = layer->GetEffectiveTransform(); |
michael@0 | 245 | void* raw = &const_cast<gfx::Matrix4x4&>(transform)._11; |
michael@0 | 246 | effect()->GetVariableByName("mLayerTransform")->SetRawValue(raw, 0, 64); |
michael@0 | 247 | effect()->GetVariableByName("fLayerOpacity")->AsScalar()->SetFloat(layer->GetEffectiveOpacity()); |
michael@0 | 248 | } |
michael@0 | 249 | |
michael@0 | 250 | protected: |
michael@0 | 251 | /* |
michael@0 | 252 | * Finds a texture for this layer's mask layer (if it has one) and sets it |
michael@0 | 253 | * as an input to the shaders. |
michael@0 | 254 | * Returns SHADER_MASK if a texture is loaded, SHADER_NO_MASK if there was no |
michael@0 | 255 | * mask layer, or a texture for the mask layer could not be loaded. |
michael@0 | 256 | */ |
michael@0 | 257 | uint8_t LoadMaskTexture(); |
michael@0 | 258 | |
michael@0 | 259 | /** |
michael@0 | 260 | * Select a shader technique using a combination of the following flags. |
michael@0 | 261 | * Not all combinations of flags are supported, and might cause an error, |
michael@0 | 262 | * check the fx file to see which shaders exist. In particular, aFlags should |
michael@0 | 263 | * include any combination of the 0x20 bit = 0 flags OR one of the 0x20 bit = 1 |
michael@0 | 264 | * flags. Mask flags can be used in either case. |
michael@0 | 265 | */ |
michael@0 | 266 | ID3D10EffectTechnique* SelectShader(uint8_t aFlags); |
michael@0 | 267 | const static uint8_t SHADER_NO_MASK = 0; |
michael@0 | 268 | const static uint8_t SHADER_MASK = 0x1; |
michael@0 | 269 | const static uint8_t SHADER_MASK_3D = 0x2; |
michael@0 | 270 | // 0x20 bit = 0 |
michael@0 | 271 | const static uint8_t SHADER_RGB = 0; |
michael@0 | 272 | const static uint8_t SHADER_RGBA = 0x4; |
michael@0 | 273 | const static uint8_t SHADER_NON_PREMUL = 0; |
michael@0 | 274 | const static uint8_t SHADER_PREMUL = 0x8; |
michael@0 | 275 | const static uint8_t SHADER_LINEAR = 0; |
michael@0 | 276 | const static uint8_t SHADER_POINT = 0x10; |
michael@0 | 277 | // 0x20 bit = 1 |
michael@0 | 278 | const static uint8_t SHADER_YCBCR = 0x20; |
michael@0 | 279 | const static uint8_t SHADER_COMPONENT_ALPHA = 0x24; |
michael@0 | 280 | const static uint8_t SHADER_SOLID = 0x28; |
michael@0 | 281 | |
michael@0 | 282 | LayerManagerD3D10 *mD3DManager; |
michael@0 | 283 | }; |
michael@0 | 284 | |
michael@0 | 285 | } /* layers */ |
michael@0 | 286 | } /* mozilla */ |
michael@0 | 287 | |
michael@0 | 288 | #endif /* GFX_LAYERMANAGERD3D9_H */ |