1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #ifndef MOZILLA_GFX_TEXTURED3D11_H
8 #define MOZILLA_GFX_TEXTURED3D11_H
9
10 #include <d3d11.h>
11
12 #include <vector>
13
14 #include "d3d9.h"
15 #include "gfxWindowsPlatform.h"
16 #include "mozilla/GfxMessageUtils.h"
17 #include "mozilla/Maybe.h"
18 #include "mozilla/gfx/2D.h"
19 #include "mozilla/layers/Compositor.h"
20 #include "mozilla/layers/SyncObject.h"
21 #include "mozilla/layers/TextureClient.h"
22 #include "mozilla/layers/TextureHost.h"
23
24 namespace mozilla {
25 namespace gl {
26 class GLBlitHelper;
27 }
28
29 namespace layers {
30
31 already_AddRefed<TextureHost> CreateTextureHostD3D11(
32 const SurfaceDescriptor& aDesc, ISurfaceAllocator* aDeallocator,
33 LayersBackend aBackend, TextureFlags aFlags);
34
35 class MOZ_RAII AutoTextureLock final {
36 public:
37 AutoTextureLock(IDXGIKeyedMutex* aMutex, HRESULT& aResult,
38 uint32_t aTimeout = 0);
39 ~AutoTextureLock();
40
41 private:
42 RefPtr<IDXGIKeyedMutex> mMutex;
43 HRESULT mResult;
44 };
45
46 class CompositorD3D11;
47
48 class D3D11TextureData final : public TextureData {
49 public:
50 // If aDevice is null, use one provided by gfxWindowsPlatform.
51 static D3D11TextureData* Create(gfx::IntSize aSize,
52 gfx::SurfaceFormat aFormat,
53 TextureAllocationFlags aAllocFlags,
54 ID3D11Device* aDevice = nullptr);
55 static D3D11TextureData* Create(gfx::SourceSurface* aSurface,
56 TextureAllocationFlags aAllocFlags,
57 ID3D11Device* aDevice = nullptr);
58
59 virtual ~D3D11TextureData();
60
61 bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
62
63 bool Lock(OpenMode aMode) override;
64
65 void Unlock() override;
66
67 already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
68
69 TextureData* CreateSimilar(LayersIPCChannel* aAllocator,
70 LayersBackend aLayersBackend, TextureFlags aFlags,
71 TextureAllocationFlags aAllocFlags) const override;
72
73 void SyncWithObject(RefPtr<SyncObjectClient> aSyncObject) override;
74
GetD3D11Texture()75 ID3D11Texture2D* GetD3D11Texture() const { return mTexture; }
76
77 void Deallocate(LayersIPCChannel* aAllocator) override;
78
AsD3D11TextureData()79 D3D11TextureData* AsD3D11TextureData() override { return this; }
80
GetTextureAllocationFlags()81 TextureAllocationFlags GetTextureAllocationFlags() const {
82 return mAllocationFlags;
83 }
84
85 void FillInfo(TextureData::Info& aInfo) const override;
86
87 bool Serialize(SurfaceDescriptor& aOutDescrptor) override;
88 void GetSubDescriptor(RemoteDecoderVideoSubDescriptor* aOutDesc) override;
89
GetYUVColorSpace()90 gfx::YUVColorSpace GetYUVColorSpace() const { return mYUVColorSpace; }
SetYUVColorSpace(gfx::YUVColorSpace aColorSpace)91 void SetYUVColorSpace(gfx::YUVColorSpace aColorSpace) {
92 mYUVColorSpace = aColorSpace;
93 }
GetColorRange()94 gfx::ColorRange GetColorRange() const { return mColorRange; }
SetColorRange(gfx::ColorRange aColorRange)95 void SetColorRange(gfx::ColorRange aColorRange) { mColorRange = aColorRange; }
96
GetSize()97 gfx::IntSize GetSize() const { return mSize; }
GetSurfaceFormat()98 gfx::SurfaceFormat GetSurfaceFormat() const { return mFormat; }
99
100 TextureFlags GetTextureFlags() const override;
101
102 private:
103 D3D11TextureData(ID3D11Texture2D* aTexture, gfx::IntSize aSize,
104 gfx::SurfaceFormat aFormat, TextureAllocationFlags aFlags);
105
106 void GetDXGIResource(IDXGIResource** aOutResource);
107
108 bool PrepareDrawTargetInLock(OpenMode aMode);
109
110 friend class gl::GLBlitHelper;
111 bool SerializeSpecific(SurfaceDescriptorD3D10* aOutDesc);
112
113 static D3D11TextureData* Create(gfx::IntSize aSize,
114 gfx::SurfaceFormat aFormat,
115 gfx::SourceSurface* aSurface,
116 TextureAllocationFlags aAllocFlags,
117 ID3D11Device* aDevice = nullptr);
118
119 // Hold on to the DrawTarget because it is expensive to create one each
120 // ::Lock.
121 RefPtr<gfx::DrawTarget> mDrawTarget;
122 const gfx::IntSize mSize;
123 const gfx::SurfaceFormat mFormat;
124 gfx::YUVColorSpace mYUVColorSpace = gfx::YUVColorSpace::Identity;
125 gfx::ColorRange mColorRange = gfx::ColorRange::LIMITED;
126 bool mNeedsClear = false;
127 bool mNeedsClearWhite = false;
128 const bool mHasSynchronization;
129 const bool mIsForOutOfBandContent;
130
131 RefPtr<ID3D11Texture2D> mTexture;
132 const TextureAllocationFlags mAllocationFlags;
133 };
134
135 class DXGIYCbCrTextureData : public TextureData {
136 friend class gl::GLBlitHelper;
137
138 public:
139 static DXGIYCbCrTextureData* Create(
140 IDirect3DTexture9* aTextureY, IDirect3DTexture9* aTextureCb,
141 IDirect3DTexture9* aTextureCr, HANDLE aHandleY, HANDLE aHandleCb,
142 HANDLE aHandleCr, const gfx::IntSize& aSize, const gfx::IntSize& aSizeY,
143 const gfx::IntSize& aSizeCbCr, gfx::ColorDepth aColorDepth,
144 gfx::YUVColorSpace aYUVColorSpace, gfx::ColorRange aColorRange);
145
146 static DXGIYCbCrTextureData* Create(
147 ID3D11Texture2D* aTextureCb, ID3D11Texture2D* aTextureY,
148 ID3D11Texture2D* aTextureCr, const gfx::IntSize& aSize,
149 const gfx::IntSize& aSizeY, const gfx::IntSize& aSizeCbCr,
150 gfx::ColorDepth aColorDepth, gfx::YUVColorSpace aYUVColorSpace,
151 gfx::ColorRange aColorRange);
152
Lock(OpenMode)153 bool Lock(OpenMode) override { return true; }
154
Unlock()155 void Unlock() override {}
156
157 void FillInfo(TextureData::Info& aInfo) const override;
158
159 void SerializeSpecific(SurfaceDescriptorDXGIYCbCr* aOutDesc);
160 bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
161 void GetSubDescriptor(RemoteDecoderVideoSubDescriptor* aOutDesc) override;
162
BorrowDrawTarget()163 already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override {
164 return nullptr;
165 }
166
167 void Deallocate(LayersIPCChannel* aAllocator) override;
168
UpdateFromSurface(gfx::SourceSurface *)169 bool UpdateFromSurface(gfx::SourceSurface*) override { return false; }
170
171 TextureFlags GetTextureFlags() const override;
172
AsDXGIYCbCrTextureData()173 DXGIYCbCrTextureData* AsDXGIYCbCrTextureData() override { return this; }
174
GetYSize()175 gfx::IntSize GetYSize() const { return mSizeY; }
176
GetCbCrSize()177 gfx::IntSize GetCbCrSize() const { return mSizeCbCr; }
178
GetColorDepth()179 gfx::ColorDepth GetColorDepth() const { return mColorDepth; }
GetYUVColorSpace()180 gfx::YUVColorSpace GetYUVColorSpace() const { return mYUVColorSpace; }
GetColorRange()181 gfx::ColorRange GetColorRange() const { return mColorRange; }
182
GetD3D11Texture(size_t index)183 ID3D11Texture2D* GetD3D11Texture(size_t index) {
184 return mD3D11Textures[index];
185 }
186
187 protected:
188 RefPtr<ID3D11Texture2D> mD3D11Textures[3];
189 RefPtr<IDirect3DTexture9> mD3D9Textures[3];
190 HANDLE mHandles[3];
191 gfx::IntSize mSize;
192 gfx::IntSize mSizeY;
193 gfx::IntSize mSizeCbCr;
194 gfx::ColorDepth mColorDepth;
195 gfx::YUVColorSpace mYUVColorSpace;
196 gfx::ColorRange mColorRange;
197 };
198
199 /**
200 * TextureSource that provides with the necessary APIs to be composited by a
201 * CompositorD3D11.
202 */
203 class TextureSourceD3D11 {
204 public:
TextureSourceD3D11()205 TextureSourceD3D11() : mFormatOverride(DXGI_FORMAT_UNKNOWN) {}
206 virtual ~TextureSourceD3D11() = default;
207
GetD3D11Texture()208 virtual ID3D11Texture2D* GetD3D11Texture() const { return mTexture; }
209 virtual ID3D11ShaderResourceView* GetShaderResourceView();
210
211 protected:
GetSize()212 virtual gfx::IntSize GetSize() const { return mSize; }
213
214 gfx::IntSize mSize;
215 RefPtr<ID3D11Texture2D> mTexture;
216 RefPtr<ID3D11ShaderResourceView> mSRV;
217 DXGI_FORMAT mFormatOverride;
218 };
219
220 /**
221 * A TextureSource that implements the DataTextureSource interface.
222 * it can be used without a TextureHost and is able to upload texture data
223 * from a gfx::DataSourceSurface.
224 */
225 class DataTextureSourceD3D11 : public DataTextureSource,
226 public TextureSourceD3D11,
227 public BigImageIterator {
228 public:
229 /// Constructor allowing the texture to perform texture uploads.
230 ///
231 /// The texture can be used as an actual DataTextureSource.
232 DataTextureSourceD3D11(ID3D11Device* aDevice, gfx::SurfaceFormat aFormat,
233 TextureFlags aFlags);
234
235 /// Constructor for textures created around DXGI shared handles, disallowing
236 /// texture uploads.
237 ///
238 /// The texture CANNOT be used as a DataTextureSource.
239 DataTextureSourceD3D11(ID3D11Device* aDevice, gfx::SurfaceFormat aFormat,
240 ID3D11Texture2D* aTexture);
241
242 DataTextureSourceD3D11(gfx::SurfaceFormat aFormat,
243 TextureSourceProvider* aProvider,
244 ID3D11Texture2D* aTexture);
245 DataTextureSourceD3D11(gfx::SurfaceFormat aFormat,
246 TextureSourceProvider* aProvider, TextureFlags aFlags);
247
248 virtual ~DataTextureSourceD3D11();
249
Name()250 const char* Name() const override { return "DataTextureSourceD3D11"; }
251
252 // DataTextureSource
253
254 bool Update(gfx::DataSourceSurface* aSurface,
255 nsIntRegion* aDestRegion = nullptr,
256 gfx::IntPoint* aSrcOffset = nullptr,
257 gfx::IntPoint* aDstOffset = nullptr) override;
258
259 // TextureSource
260
AsSourceD3D11()261 TextureSourceD3D11* AsSourceD3D11() override { return this; }
262
263 ID3D11Texture2D* GetD3D11Texture() const override;
264
265 ID3D11ShaderResourceView* GetShaderResourceView() override;
266
267 // Returns nullptr if this texture was created by a DXGI TextureHost.
AsDataTextureSource()268 DataTextureSource* AsDataTextureSource() override {
269 return mAllowTextureUploads ? this : nullptr;
270 }
271
DeallocateDeviceData()272 void DeallocateDeviceData() override { mTexture = nullptr; }
273
GetSize()274 gfx::IntSize GetSize() const override { return mSize; }
275
GetFormat()276 gfx::SurfaceFormat GetFormat() const override { return mFormat; }
277
278 // BigImageIterator
279
AsBigImageIterator()280 BigImageIterator* AsBigImageIterator() override {
281 return mIsTiled ? this : nullptr;
282 }
283
GetTileCount()284 size_t GetTileCount() override { return mTileTextures.size(); }
285
NextTile()286 bool NextTile() override { return (++mCurrentTile < mTileTextures.size()); }
287
288 gfx::IntRect GetTileRect() override;
289
EndBigImageIteration()290 void EndBigImageIteration() override { mIterating = false; }
291
BeginBigImageIteration()292 void BeginBigImageIteration() override {
293 mIterating = true;
294 mCurrentTile = 0;
295 }
296
297 RefPtr<TextureSource> ExtractCurrentTile() override;
298
299 void Reset();
300
301 protected:
302 gfx::IntRect GetTileRect(uint32_t aIndex) const;
303
304 std::vector<RefPtr<ID3D11Texture2D> > mTileTextures;
305 std::vector<RefPtr<ID3D11ShaderResourceView> > mTileSRVs;
306 RefPtr<ID3D11Device> mDevice;
307 gfx::SurfaceFormat mFormat;
308 TextureFlags mFlags;
309 uint32_t mCurrentTile;
310 bool mIsTiled;
311 bool mIterating;
312 // Sadly, the code was originally organized so that this class is used both in
313 // the cases where we want to perform texture uploads through the
314 // DataTextureSource interface, and the cases where we wrap the texture around
315 // an existing DXGI handle in which case we should not use it as a
316 // DataTextureSource. This member differentiates the two scenarios. When it is
317 // false the texture "pretends" to not be a DataTextureSource.
318 bool mAllowTextureUploads;
319 };
320
321 /**
322 * A TextureHost for shared D3D11 textures.
323 */
324 class DXGITextureHostD3D11 : public TextureHost {
325 public:
326 DXGITextureHostD3D11(TextureFlags aFlags,
327 const SurfaceDescriptorD3D10& aDescriptor);
328
329 bool BindTextureSource(CompositableTextureSourceRef& aTexture) override;
330 bool AcquireTextureSource(CompositableTextureSourceRef& aTexture) override;
331
DeallocateDeviceData()332 void DeallocateDeviceData() override {}
333
334 void SetTextureSourceProvider(TextureSourceProvider* aProvider) override;
335
GetFormat()336 gfx::SurfaceFormat GetFormat() const override { return mFormat; }
337
338 bool Lock() override;
339 void Unlock() override;
340
341 bool LockWithoutCompositor() override;
342 void UnlockWithoutCompositor() override;
343
GetSize()344 gfx::IntSize GetSize() const override { return mSize; }
GetYUVColorSpace()345 gfx::YUVColorSpace GetYUVColorSpace() const override {
346 return mYUVColorSpace;
347 }
GetColorRange()348 gfx::ColorRange GetColorRange() const override { return mColorRange; }
349
350 already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override;
351
352 void CreateRenderTexture(
353 const wr::ExternalImageId& aExternalImageId) override;
354
355 uint32_t NumSubTextures() override;
356
357 void PushResourceUpdates(wr::TransactionBuilder& aResources,
358 ResourceUpdateOp aOp,
359 const Range<wr::ImageKey>& aImageKeys,
360 const wr::ExternalImageId& aExtID) override;
361
362 void PushDisplayItems(wr::DisplayListBuilder& aBuilder,
363 const wr::LayoutRect& aBounds,
364 const wr::LayoutRect& aClip, wr::ImageRendering aFilter,
365 const Range<wr::ImageKey>& aImageKeys,
366 PushDisplayItemFlagSet aFlags) override;
367
368 bool SupportsExternalCompositing(WebRenderBackend aBackend) override;
369
370 protected:
371 bool LockInternal();
372 void UnlockInternal();
373
374 bool EnsureTextureSource();
375
376 RefPtr<ID3D11Device> GetDevice();
377
378 bool EnsureTexture();
379
380 RefPtr<ID3D11Device> mDevice;
381 RefPtr<ID3D11Texture2D> mTexture;
382 RefPtr<DataTextureSourceD3D11> mTextureSource;
383 gfx::IntSize mSize;
384 WindowsHandle mHandle;
385 gfx::SurfaceFormat mFormat;
386 const gfx::YUVColorSpace mYUVColorSpace;
387 const gfx::ColorRange mColorRange;
388 bool mIsLocked;
389 };
390
391 class DXGIYCbCrTextureHostD3D11 : public TextureHost {
392 public:
393 DXGIYCbCrTextureHostD3D11(TextureFlags aFlags,
394 const SurfaceDescriptorDXGIYCbCr& aDescriptor);
395
396 bool BindTextureSource(CompositableTextureSourceRef& aTexture) override;
397 bool AcquireTextureSource(CompositableTextureSourceRef& aTexture) override;
398
DeallocateDeviceData()399 void DeallocateDeviceData() override {}
400
401 void SetTextureSourceProvider(TextureSourceProvider* aProvider) override;
402
GetFormat()403 gfx::SurfaceFormat GetFormat() const override {
404 return gfx::SurfaceFormat::YUV;
405 }
406
GetColorDepth()407 gfx::ColorDepth GetColorDepth() const override { return mColorDepth; }
GetYUVColorSpace()408 gfx::YUVColorSpace GetYUVColorSpace() const override {
409 return mYUVColorSpace;
410 }
GetColorRange()411 gfx::ColorRange GetColorRange() const override { return mColorRange; }
412
413 bool Lock() override;
414
415 void Unlock() override;
416
GetSize()417 gfx::IntSize GetSize() const override { return mSize; }
418
GetAsSurface()419 already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override {
420 return nullptr;
421 }
422
423 void CreateRenderTexture(
424 const wr::ExternalImageId& aExternalImageId) override;
425
426 uint32_t NumSubTextures() override;
427
428 void PushResourceUpdates(wr::TransactionBuilder& aResources,
429 ResourceUpdateOp aOp,
430 const Range<wr::ImageKey>& aImageKeys,
431 const wr::ExternalImageId& aExtID) override;
432
433 void PushDisplayItems(wr::DisplayListBuilder& aBuilder,
434 const wr::LayoutRect& aBounds,
435 const wr::LayoutRect& aClip, wr::ImageRendering aFilter,
436 const Range<wr::ImageKey>& aImageKeys,
437 PushDisplayItemFlagSet aFlags) override;
438
439 bool SupportsExternalCompositing(WebRenderBackend aBackend) override;
440
441 private:
442 bool EnsureTextureSource();
443
444 protected:
445 RefPtr<ID3D11Device> GetDevice();
446
447 bool EnsureTexture();
448
449 RefPtr<ID3D11Texture2D> mTextures[3];
450 RefPtr<DataTextureSourceD3D11> mTextureSources[3];
451
452 gfx::IntSize mSize;
453 gfx::IntSize mSizeY;
454 gfx::IntSize mSizeCbCr;
455 WindowsHandle mHandles[3];
456 bool mIsLocked;
457 gfx::ColorDepth mColorDepth;
458 gfx::YUVColorSpace mYUVColorSpace;
459 gfx::ColorRange mColorRange;
460 };
461
462 class CompositingRenderTargetD3D11 : public CompositingRenderTarget,
463 public TextureSourceD3D11 {
464 public:
465 CompositingRenderTargetD3D11(
466 ID3D11Texture2D* aTexture, const gfx::IntPoint& aOrigin,
467 DXGI_FORMAT aFormatOverride = DXGI_FORMAT_UNKNOWN);
468
Name()469 const char* Name() const override { return "CompositingRenderTargetD3D11"; }
470
AsSourceD3D11()471 TextureSourceD3D11* AsSourceD3D11() override { return this; }
472
473 void BindRenderTarget(ID3D11DeviceContext* aContext);
474
475 gfx::IntSize GetSize() const override;
476
SetSize(const gfx::IntSize & aSize)477 void SetSize(const gfx::IntSize& aSize) { mSize = aSize; }
478
479 private:
480 friend class CompositorD3D11;
481 RefPtr<ID3D11RenderTargetView> mRTView;
482 };
483
484 class SyncObjectD3D11Host : public SyncObjectHost {
485 public:
486 explicit SyncObjectD3D11Host(ID3D11Device* aDevice);
487
488 bool Init() override;
489
490 SyncHandle GetSyncHandle() override;
491
492 bool Synchronize(bool aFallible) override;
493
GetKeyedMutex()494 IDXGIKeyedMutex* GetKeyedMutex() { return mKeyedMutex.get(); };
495
496 private:
497 virtual ~SyncObjectD3D11Host() = default;
498
499 SyncHandle mSyncHandle;
500 RefPtr<ID3D11Device> mDevice;
501 RefPtr<IDXGIResource> mSyncTexture;
502 RefPtr<IDXGIKeyedMutex> mKeyedMutex;
503 };
504
505 class SyncObjectD3D11Client : public SyncObjectClient {
506 public:
507 SyncObjectD3D11Client(SyncHandle aSyncHandle, ID3D11Device* aDevice);
508
509 bool Synchronize(bool aFallible) override;
510
511 bool IsSyncObjectValid() override;
512
EnsureInitialized()513 void EnsureInitialized() override {}
514
GetSyncType()515 SyncType GetSyncType() override { return SyncType::D3D11; }
516
517 void RegisterTexture(ID3D11Texture2D* aTexture);
518
519 protected:
520 explicit SyncObjectD3D11Client(SyncHandle aSyncHandle);
521 bool Init(ID3D11Device* aDevice, bool aFallible);
522 bool SynchronizeInternal(ID3D11Device* aDevice, bool aFallible);
523 Mutex mSyncLock;
524 RefPtr<ID3D11Texture2D> mSyncTexture;
525 std::vector<ID3D11Texture2D*> mSyncedTextures;
526
527 private:
528 const SyncHandle mSyncHandle;
529 RefPtr<IDXGIKeyedMutex> mKeyedMutex;
530 const RefPtr<ID3D11Device> mDevice;
531 };
532
533 class SyncObjectD3D11ClientContentDevice : public SyncObjectD3D11Client {
534 public:
535 explicit SyncObjectD3D11ClientContentDevice(SyncHandle aSyncHandle);
536
537 bool Synchronize(bool aFallible) override;
538
539 bool IsSyncObjectValid() override;
540
541 void EnsureInitialized() override;
542
543 private:
544 RefPtr<ID3D11Device> mContentDevice;
545 };
546
GetMaxTextureSizeForFeatureLevel(D3D_FEATURE_LEVEL aFeatureLevel)547 inline uint32_t GetMaxTextureSizeForFeatureLevel(
548 D3D_FEATURE_LEVEL aFeatureLevel) {
549 int32_t maxTextureSize;
550 switch (aFeatureLevel) {
551 case D3D_FEATURE_LEVEL_11_1:
552 case D3D_FEATURE_LEVEL_11_0:
553 maxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
554 break;
555 case D3D_FEATURE_LEVEL_10_1:
556 case D3D_FEATURE_LEVEL_10_0:
557 maxTextureSize = D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;
558 break;
559 case D3D_FEATURE_LEVEL_9_3:
560 maxTextureSize = D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
561 break;
562 default:
563 maxTextureSize = D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
564 }
565 return maxTextureSize;
566 }
567
568 uint32_t GetMaxTextureSizeFromDevice(ID3D11Device* aDevice);
569 void ReportTextureMemoryUsage(ID3D11Texture2D* aTexture, size_t aBytes);
570
571 class AutoLockD3D11Texture {
572 public:
573 explicit AutoLockD3D11Texture(ID3D11Texture2D* aTexture);
574 ~AutoLockD3D11Texture();
575
576 private:
577 RefPtr<IDXGIKeyedMutex> mMutex;
578 };
579
580 class D3D11MTAutoEnter {
581 public:
D3D11MTAutoEnter(already_AddRefed<ID3D10Multithread> aMT)582 explicit D3D11MTAutoEnter(already_AddRefed<ID3D10Multithread> aMT)
583 : mMT(aMT) {
584 if (mMT) {
585 mMT->Enter();
586 }
587 }
~D3D11MTAutoEnter()588 ~D3D11MTAutoEnter() {
589 if (mMT) {
590 mMT->Leave();
591 }
592 }
593
594 private:
595 RefPtr<ID3D10Multithread> mMT;
596 };
597
598 } // namespace layers
599 } // namespace mozilla
600
601 #endif /* MOZILLA_GFX_TEXTURED3D11_H */
602