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