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