|
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|
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 MOZILLA_GFX_TEXTURED3D9_H |
|
7 #define MOZILLA_GFX_TEXTURED3D9_H |
|
8 |
|
9 #include "mozilla/layers/Compositor.h" |
|
10 #include "mozilla/layers/TextureClient.h" |
|
11 #include "mozilla/layers/TextureHost.h" |
|
12 #include "mozilla/GfxMessageUtils.h" |
|
13 #include "gfxWindowsPlatform.h" |
|
14 #include "d3d9.h" |
|
15 #include <vector> |
|
16 #include "DeviceManagerD3D9.h" |
|
17 |
|
18 namespace mozilla { |
|
19 namespace gfxs { |
|
20 class DrawTarget; |
|
21 } |
|
22 } |
|
23 |
|
24 namespace mozilla { |
|
25 namespace layers { |
|
26 |
|
27 class CompositorD3D9; |
|
28 |
|
29 class TextureSourceD3D9 |
|
30 { |
|
31 friend class DeviceManagerD3D9; |
|
32 |
|
33 public: |
|
34 TextureSourceD3D9() |
|
35 : mPreviousHost(nullptr) |
|
36 , mNextHost(nullptr) |
|
37 , mCreatingDeviceManager(nullptr) |
|
38 {} |
|
39 virtual ~TextureSourceD3D9(); |
|
40 |
|
41 virtual IDirect3DTexture9* GetD3D9Texture() { return mTexture; } |
|
42 |
|
43 StereoMode GetStereoMode() const { return mStereoMode; }; |
|
44 |
|
45 // Release all texture memory resources held by the texture host. |
|
46 virtual void ReleaseTextureResources() |
|
47 { |
|
48 mTexture = nullptr; |
|
49 } |
|
50 |
|
51 protected: |
|
52 virtual gfx::IntSize GetSize() const { return mSize; } |
|
53 void SetSize(const gfx::IntSize& aSize) { mSize = aSize; } |
|
54 |
|
55 // Helper methods for creating and copying textures. |
|
56 TemporaryRef<IDirect3DTexture9> InitTextures( |
|
57 DeviceManagerD3D9* aDeviceManager, |
|
58 const gfx::IntSize &aSize, |
|
59 _D3DFORMAT aFormat, |
|
60 RefPtr<IDirect3DSurface9>& aSurface, |
|
61 D3DLOCKED_RECT& aLockedRect); |
|
62 |
|
63 TemporaryRef<IDirect3DTexture9> DataToTexture( |
|
64 DeviceManagerD3D9* aDeviceManager, |
|
65 unsigned char *aData, |
|
66 int aStride, |
|
67 const gfx::IntSize &aSize, |
|
68 _D3DFORMAT aFormat, |
|
69 uint32_t aBPP); |
|
70 |
|
71 // aTexture should be in SYSTEMMEM, returns a texture in the default |
|
72 // pool (that is, in video memory). |
|
73 TemporaryRef<IDirect3DTexture9> TextureToTexture( |
|
74 DeviceManagerD3D9* aDeviceManager, |
|
75 IDirect3DTexture9* aTexture, |
|
76 const gfx::IntSize& aSize, |
|
77 _D3DFORMAT aFormat); |
|
78 |
|
79 TemporaryRef<IDirect3DTexture9> SurfaceToTexture( |
|
80 DeviceManagerD3D9* aDeviceManager, |
|
81 gfxWindowsSurface* aSurface, |
|
82 const gfx::IntSize& aSize, |
|
83 _D3DFORMAT aFormat); |
|
84 |
|
85 gfx::IntSize mSize; |
|
86 |
|
87 // Linked list of all objects holding d3d9 textures. |
|
88 TextureSourceD3D9* mPreviousHost; |
|
89 TextureSourceD3D9* mNextHost; |
|
90 // The device manager that created our textures. |
|
91 DeviceManagerD3D9* mCreatingDeviceManager; |
|
92 |
|
93 StereoMode mStereoMode; |
|
94 RefPtr<IDirect3DTexture9> mTexture; |
|
95 }; |
|
96 |
|
97 /** |
|
98 * A TextureSource that implements the DataTextureSource interface. |
|
99 * it can be used without a TextureHost and is able to upload texture data |
|
100 * from a gfx::DataSourceSurface. |
|
101 */ |
|
102 class DataTextureSourceD3D9 : public DataTextureSource |
|
103 , public TextureSourceD3D9 |
|
104 , public TileIterator |
|
105 { |
|
106 public: |
|
107 DataTextureSourceD3D9(gfx::SurfaceFormat aFormat, |
|
108 CompositorD3D9* aCompositor, |
|
109 TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT, |
|
110 StereoMode aStereoMode = StereoMode::MONO); |
|
111 |
|
112 DataTextureSourceD3D9(gfx::SurfaceFormat aFormat, |
|
113 gfx::IntSize aSize, |
|
114 CompositorD3D9* aCompositor, |
|
115 IDirect3DTexture9* aTexture, |
|
116 TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT); |
|
117 |
|
118 virtual ~DataTextureSourceD3D9(); |
|
119 |
|
120 // DataTextureSource |
|
121 |
|
122 virtual bool Update(gfx::DataSourceSurface* aSurface, |
|
123 nsIntRegion* aDestRegion = nullptr, |
|
124 gfx::IntPoint* aSrcOffset = nullptr) MOZ_OVERRIDE; |
|
125 |
|
126 // TextureSource |
|
127 |
|
128 virtual TextureSourceD3D9* AsSourceD3D9() MOZ_OVERRIDE { return this; } |
|
129 |
|
130 virtual IDirect3DTexture9* GetD3D9Texture() MOZ_OVERRIDE; |
|
131 |
|
132 virtual DataTextureSource* AsDataTextureSource() MOZ_OVERRIDE { return this; } |
|
133 |
|
134 virtual void DeallocateDeviceData() MOZ_OVERRIDE { mTexture = nullptr; } |
|
135 |
|
136 virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; } |
|
137 |
|
138 virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; } |
|
139 |
|
140 virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; |
|
141 |
|
142 // TileIterator |
|
143 |
|
144 virtual TileIterator* AsTileIterator() MOZ_OVERRIDE { return mIsTiled ? this : nullptr; } |
|
145 |
|
146 virtual size_t GetTileCount() MOZ_OVERRIDE { return mTileTextures.size(); } |
|
147 |
|
148 virtual bool NextTile() MOZ_OVERRIDE { return (++mCurrentTile < mTileTextures.size()); } |
|
149 |
|
150 virtual nsIntRect GetTileRect() MOZ_OVERRIDE; |
|
151 |
|
152 virtual void EndTileIteration() MOZ_OVERRIDE { mIterating = false; } |
|
153 |
|
154 virtual void BeginTileIteration() MOZ_OVERRIDE |
|
155 { |
|
156 mIterating = true; |
|
157 mCurrentTile = 0; |
|
158 } |
|
159 |
|
160 /** |
|
161 * Copy the content of aTexture using the GPU. |
|
162 */ |
|
163 bool UpdateFromTexture(IDirect3DTexture9* aTexture, const nsIntRegion* aRegion); |
|
164 |
|
165 // To use with DIBTextureHostD3D9 |
|
166 |
|
167 bool Update(gfxWindowsSurface* aSurface); |
|
168 |
|
169 protected: |
|
170 gfx::IntRect GetTileRect(uint32_t aTileIndex) const; |
|
171 |
|
172 void Reset(); |
|
173 |
|
174 std::vector< RefPtr<IDirect3DTexture9> > mTileTextures; |
|
175 RefPtr<CompositorD3D9> mCompositor; |
|
176 gfx::SurfaceFormat mFormat; |
|
177 uint32_t mCurrentTile; |
|
178 TextureFlags mFlags; |
|
179 bool mIsTiled; |
|
180 bool mIterating; |
|
181 }; |
|
182 |
|
183 /** |
|
184 * Can only be drawn into through Cairo and need a D3D9 context on the client side. |
|
185 * The corresponding TextureHost is TextureHostD3D9. |
|
186 */ |
|
187 class CairoTextureClientD3D9 : public TextureClient |
|
188 { |
|
189 public: |
|
190 CairoTextureClientD3D9(gfx::SurfaceFormat aFormat, TextureFlags aFlags); |
|
191 |
|
192 virtual ~CairoTextureClientD3D9(); |
|
193 |
|
194 // TextureClient |
|
195 |
|
196 virtual bool IsAllocated() const MOZ_OVERRIDE { return !!mTexture; } |
|
197 |
|
198 virtual bool Lock(OpenMode aOpenMode) MOZ_OVERRIDE; |
|
199 |
|
200 virtual void Unlock() MOZ_OVERRIDE; |
|
201 |
|
202 virtual bool IsLocked() const MOZ_OVERRIDE { return mIsLocked; } |
|
203 |
|
204 virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE; |
|
205 |
|
206 virtual gfx::IntSize GetSize() const { return mSize; } |
|
207 |
|
208 virtual gfx::SurfaceFormat GetFormat() const { return mFormat; } |
|
209 |
|
210 virtual TextureClientData* DropTextureData() MOZ_OVERRIDE; |
|
211 |
|
212 virtual bool CanExposeDrawTarget() const MOZ_OVERRIDE { return true; } |
|
213 |
|
214 virtual TemporaryRef<gfx::DrawTarget> GetAsDrawTarget() MOZ_OVERRIDE; |
|
215 |
|
216 virtual bool AllocateForSurface(gfx::IntSize aSize, |
|
217 TextureAllocationFlags aFlags = ALLOC_DEFAULT) MOZ_OVERRIDE; |
|
218 |
|
219 virtual bool HasInternalBuffer() const MOZ_OVERRIDE { return true; } |
|
220 |
|
221 private: |
|
222 RefPtr<IDirect3DTexture9> mTexture; |
|
223 nsRefPtr<IDirect3DSurface9> mD3D9Surface; |
|
224 RefPtr<gfx::DrawTarget> mDrawTarget; |
|
225 nsRefPtr<gfxASurface> mSurface; |
|
226 gfx::IntSize mSize; |
|
227 gfx::SurfaceFormat mFormat; |
|
228 bool mIsLocked; |
|
229 bool mNeedsClear; |
|
230 bool mLockRect; |
|
231 }; |
|
232 |
|
233 /** |
|
234 * Can only be drawn into through Cairo. |
|
235 * Prefer CairoTextureClientD3D9 when possible. |
|
236 * The coresponding TextureHost is DIBTextureHostD3D9. |
|
237 */ |
|
238 class DIBTextureClientD3D9 : public TextureClient |
|
239 { |
|
240 public: |
|
241 DIBTextureClientD3D9(gfx::SurfaceFormat aFormat, TextureFlags aFlags); |
|
242 |
|
243 virtual ~DIBTextureClientD3D9(); |
|
244 |
|
245 // TextureClient |
|
246 |
|
247 virtual bool IsAllocated() const MOZ_OVERRIDE { return !!mSurface; } |
|
248 |
|
249 virtual bool Lock(OpenMode aOpenMode) MOZ_OVERRIDE; |
|
250 |
|
251 virtual void Unlock() MOZ_OVERRIDE; |
|
252 |
|
253 virtual bool IsLocked() const MOZ_OVERRIDE { return mIsLocked; } |
|
254 |
|
255 virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE; |
|
256 |
|
257 virtual gfx::IntSize GetSize() const { return mSize; } |
|
258 |
|
259 virtual gfx::SurfaceFormat GetFormat() const { return mFormat; } |
|
260 |
|
261 virtual TextureClientData* DropTextureData() MOZ_OVERRIDE; |
|
262 |
|
263 virtual bool CanExposeDrawTarget() const MOZ_OVERRIDE { return true; } |
|
264 |
|
265 virtual TemporaryRef<gfx::DrawTarget> GetAsDrawTarget() MOZ_OVERRIDE; |
|
266 |
|
267 virtual bool AllocateForSurface(gfx::IntSize aSize, |
|
268 TextureAllocationFlags aFlags = ALLOC_DEFAULT) MOZ_OVERRIDE; |
|
269 |
|
270 virtual bool HasInternalBuffer() const MOZ_OVERRIDE { return true; } |
|
271 |
|
272 protected: |
|
273 nsRefPtr<gfxWindowsSurface> mSurface; |
|
274 RefPtr<gfx::DrawTarget> mDrawTarget; |
|
275 gfx::IntSize mSize; |
|
276 gfx::SurfaceFormat mFormat; |
|
277 bool mIsLocked; |
|
278 }; |
|
279 |
|
280 /** |
|
281 * Wraps a D3D9 texture, shared with the compositor though DXGI. |
|
282 * At the moment it is only used with D3D11 compositing, and the corresponding |
|
283 * TextureHost is DXGITextureHostD3D11. |
|
284 */ |
|
285 class SharedTextureClientD3D9 : public TextureClient |
|
286 { |
|
287 public: |
|
288 SharedTextureClientD3D9(gfx::SurfaceFormat aFormat, TextureFlags aFlags); |
|
289 |
|
290 virtual ~SharedTextureClientD3D9(); |
|
291 |
|
292 // TextureClient |
|
293 |
|
294 virtual bool IsAllocated() const MOZ_OVERRIDE { return !!mTexture; } |
|
295 |
|
296 virtual bool Lock(OpenMode aOpenMode) MOZ_OVERRIDE; |
|
297 |
|
298 virtual void Unlock() MOZ_OVERRIDE; |
|
299 |
|
300 virtual bool IsLocked() const MOZ_OVERRIDE { return mIsLocked; } |
|
301 |
|
302 virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE; |
|
303 |
|
304 void InitWith(IDirect3DTexture9* aTexture, HANDLE aSharedHandle, D3DSURFACE_DESC aDesc) |
|
305 { |
|
306 MOZ_ASSERT(!mTexture); |
|
307 mTexture = aTexture; |
|
308 mHandle = aSharedHandle; |
|
309 mDesc = aDesc; |
|
310 } |
|
311 |
|
312 virtual gfx::IntSize GetSize() const |
|
313 { |
|
314 return gfx::IntSize(mDesc.Width, mDesc.Height); |
|
315 } |
|
316 |
|
317 virtual TextureClientData* DropTextureData() MOZ_OVERRIDE; |
|
318 |
|
319 virtual bool HasInternalBuffer() const MOZ_OVERRIDE { return true; } |
|
320 |
|
321 private: |
|
322 RefPtr<IDirect3DTexture9> mTexture; |
|
323 gfx::SurfaceFormat mFormat; |
|
324 HANDLE mHandle; |
|
325 D3DSURFACE_DESC mDesc; |
|
326 bool mIsLocked; |
|
327 }; |
|
328 |
|
329 class TextureHostD3D9 : public TextureHost |
|
330 { |
|
331 public: |
|
332 TextureHostD3D9(TextureFlags aFlags, |
|
333 const SurfaceDescriptorD3D9& aDescriptor); |
|
334 |
|
335 virtual NewTextureSource* GetTextureSources() MOZ_OVERRIDE; |
|
336 |
|
337 virtual void DeallocateDeviceData() MOZ_OVERRIDE; |
|
338 |
|
339 virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; |
|
340 |
|
341 virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; } |
|
342 |
|
343 virtual bool Lock() MOZ_OVERRIDE; |
|
344 |
|
345 virtual void Unlock() MOZ_OVERRIDE; |
|
346 |
|
347 virtual void Updated(const nsIntRegion* aRegion) MOZ_OVERRIDE; |
|
348 |
|
349 virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; } |
|
350 |
|
351 virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE |
|
352 { |
|
353 return nullptr; |
|
354 } |
|
355 |
|
356 virtual bool HasInternalBuffer() const MOZ_OVERRIDE { return true; } |
|
357 |
|
358 protected: |
|
359 TextureHostD3D9(TextureFlags aFlags); |
|
360 IDirect3DDevice9* GetDevice(); |
|
361 |
|
362 RefPtr<DataTextureSourceD3D9> mTextureSource; |
|
363 RefPtr<IDirect3DTexture9> mTexture; |
|
364 RefPtr<CompositorD3D9> mCompositor; |
|
365 gfx::IntSize mSize; |
|
366 gfx::SurfaceFormat mFormat; |
|
367 bool mIsLocked; |
|
368 }; |
|
369 |
|
370 class DIBTextureHostD3D9 : public TextureHost |
|
371 { |
|
372 public: |
|
373 DIBTextureHostD3D9(TextureFlags aFlags, |
|
374 const SurfaceDescriptorDIB& aDescriptor); |
|
375 |
|
376 virtual NewTextureSource* GetTextureSources() MOZ_OVERRIDE; |
|
377 |
|
378 virtual void DeallocateDeviceData() MOZ_OVERRIDE; |
|
379 |
|
380 virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; |
|
381 |
|
382 virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; } |
|
383 |
|
384 virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; } |
|
385 |
|
386 virtual bool Lock() MOZ_OVERRIDE; |
|
387 |
|
388 virtual void Unlock() MOZ_OVERRIDE; |
|
389 |
|
390 virtual void Updated(const nsIntRegion* aRegion = nullptr); |
|
391 |
|
392 virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE |
|
393 { |
|
394 return nullptr; // TODO: cf bug 872568 |
|
395 } |
|
396 |
|
397 protected: |
|
398 nsRefPtr<gfxWindowsSurface> mSurface; |
|
399 RefPtr<DataTextureSourceD3D9> mTextureSource; |
|
400 RefPtr<CompositorD3D9> mCompositor; |
|
401 gfx::SurfaceFormat mFormat; |
|
402 gfx::IntSize mSize; |
|
403 bool mIsLocked; |
|
404 }; |
|
405 |
|
406 class DXGITextureHostD3D9 : public TextureHost |
|
407 { |
|
408 public: |
|
409 DXGITextureHostD3D9(TextureFlags aFlags, |
|
410 const SurfaceDescriptorD3D10& aDescriptor); |
|
411 |
|
412 virtual NewTextureSource* GetTextureSources() MOZ_OVERRIDE; |
|
413 |
|
414 virtual void DeallocateDeviceData() MOZ_OVERRIDE; |
|
415 |
|
416 virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; |
|
417 |
|
418 virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; } |
|
419 |
|
420 virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; } |
|
421 |
|
422 virtual bool Lock() MOZ_OVERRIDE; |
|
423 |
|
424 virtual void Unlock() MOZ_OVERRIDE; |
|
425 |
|
426 virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE |
|
427 { |
|
428 return nullptr; // TODO: cf bug 872568 |
|
429 } |
|
430 |
|
431 protected: |
|
432 RefPtr<DataTextureSourceD3D9> mTextureSource; |
|
433 RefPtr<CompositorD3D9> mCompositor; |
|
434 WindowsHandle mHandle; |
|
435 gfx::SurfaceFormat mFormat; |
|
436 gfx::IntSize mSize; |
|
437 bool mIsLocked; |
|
438 }; |
|
439 |
|
440 class CompositingRenderTargetD3D9 : public CompositingRenderTarget, |
|
441 public TextureSourceD3D9 |
|
442 { |
|
443 public: |
|
444 CompositingRenderTargetD3D9(IDirect3DTexture9* aTexture, |
|
445 SurfaceInitMode aInit, |
|
446 const gfx::IntRect& aRect); |
|
447 // use for rendering to the main window, cannot be rendered as a texture |
|
448 CompositingRenderTargetD3D9(IDirect3DSurface9* aSurface, |
|
449 SurfaceInitMode aInit, |
|
450 const gfx::IntRect& aRect); |
|
451 virtual ~CompositingRenderTargetD3D9(); |
|
452 |
|
453 virtual TextureSourceD3D9* AsSourceD3D9() MOZ_OVERRIDE |
|
454 { |
|
455 MOZ_ASSERT(mTexture, |
|
456 "No texture, can't be indirectly rendered. Is this the screen backbuffer?"); |
|
457 return this; |
|
458 } |
|
459 |
|
460 virtual gfx::IntSize GetSize() const MOZ_OVERRIDE; |
|
461 |
|
462 void BindRenderTarget(IDirect3DDevice9* aDevice); |
|
463 |
|
464 IDirect3DSurface9* GetD3D9Surface() const { return mSurface; } |
|
465 |
|
466 private: |
|
467 friend class CompositorD3D9; |
|
468 |
|
469 nsRefPtr<IDirect3DSurface9> mSurface; |
|
470 SurfaceInitMode mInitMode; |
|
471 bool mInitialized; |
|
472 }; |
|
473 |
|
474 } |
|
475 } |
|
476 |
|
477 #endif /* MOZILLA_GFX_TEXTURED3D9_H */ |