Backed out 2 changesets (bug 1931901) for causing build bustages in TelemetryScalar...
[gecko.git] / gfx / layers / d3d11 / TextureD3D11.h
blob692926c84f6b62d35630b2ba239a00fb7cc715a7
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/. */
7 #ifndef MOZILLA_GFX_TEXTURED3D11_H
8 #define MOZILLA_GFX_TEXTURED3D11_H
10 #include <d3d11.h>
11 #include <d3d11_1.h>
12 #include <vector>
14 #include "d3d9.h"
15 #include "gfxWindowsPlatform.h"
16 #include "mozilla/DataMutex.h"
17 #include "mozilla/GfxMessageUtils.h"
18 #include "mozilla/Maybe.h"
19 #include "mozilla/gfx/2D.h"
20 #include "mozilla/layers/Compositor.h"
21 #include "mozilla/layers/SyncObject.h"
22 #include "mozilla/layers/TextureClient.h"
23 #include "mozilla/layers/TextureHost.h"
25 namespace mozilla {
27 namespace gfx {
28 class FileHandleWrapper;
29 struct FenceInfo;
30 } // namespace gfx
32 namespace gl {
33 class GLBlitHelper;
36 namespace layers {
38 gfx::DeviceResetReason DXGIErrorToDeviceResetReason(HRESULT aError);
40 already_AddRefed<TextureHost> CreateTextureHostD3D11(
41 const SurfaceDescriptor& aDesc, ISurfaceAllocator* aDeallocator,
42 LayersBackend aBackend, TextureFlags aFlags);
44 class MOZ_RAII AutoTextureLock final {
45 public:
46 AutoTextureLock(IDXGIKeyedMutex* aMutex, HRESULT& aResult,
47 uint32_t aTimeout = 0);
48 ~AutoTextureLock();
50 private:
51 RefPtr<IDXGIKeyedMutex> mMutex;
52 HRESULT mResult;
55 class CompositorD3D11;
56 class IMFSampleUsageInfo;
57 class VideoProcessorD3D11;
59 class D3D11TextureData final : public TextureData {
60 public:
61 // If aDevice is null, use one provided by gfxWindowsPlatform.
62 static D3D11TextureData* Create(gfx::IntSize aSize,
63 gfx::SurfaceFormat aFormat,
64 TextureAllocationFlags aAllocFlags,
65 ID3D11Device* aDevice = nullptr);
66 static D3D11TextureData* Create(gfx::SourceSurface* aSurface,
67 TextureAllocationFlags aAllocFlags,
68 ID3D11Device* aDevice = nullptr);
70 static already_AddRefed<TextureClient> CreateTextureClient(
71 ID3D11Texture2D* aTexture, uint32_t aIndex, gfx::IntSize aSize,
72 gfx::SurfaceFormat aFormat, gfx::ColorSpace2 aColorSpace,
73 gfx::ColorRange aColorRange, KnowsCompositor* aKnowsCompositor,
74 RefPtr<IMFSampleUsageInfo> aUsageInfo);
76 virtual ~D3D11TextureData();
78 bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
80 bool Lock(OpenMode aMode) override;
82 void Unlock() override;
84 already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
86 TextureData* CreateSimilar(LayersIPCChannel* aAllocator,
87 LayersBackend aLayersBackend, TextureFlags aFlags,
88 TextureAllocationFlags aAllocFlags) const override;
90 void SyncWithObject(RefPtr<SyncObjectClient> aSyncObject) override;
92 ID3D11Texture2D* GetD3D11Texture() const { return mTexture; }
94 void Deallocate(LayersIPCChannel* aAllocator) override;
96 D3D11TextureData* AsD3D11TextureData() override { return this; }
98 TextureAllocationFlags GetTextureAllocationFlags() const {
99 return mAllocationFlags;
102 TextureType GetTextureType() const override { return TextureType::D3D11; }
104 void FillInfo(TextureData::Info& aInfo) const override;
106 bool Serialize(SurfaceDescriptor& aOutDescrptor) override;
107 void GetSubDescriptor(RemoteDecoderVideoSubDescriptor* aOutDesc) override;
109 gfx::ColorRange GetColorRange() const { return mColorRange; }
110 void SetColorRange(gfx::ColorRange aColorRange) { mColorRange = aColorRange; }
112 gfx::IntSize GetSize() const { return mSize; }
113 gfx::SurfaceFormat GetSurfaceFormat() const { return mFormat; }
115 TextureFlags GetTextureFlags() const override;
117 void SetGpuProcessTextureId(GpuProcessTextureId aTextureId) {
118 mGpuProcessTextureId = Some(aTextureId);
121 Maybe<GpuProcessTextureId> GetGpuProcessTextureId() {
122 return mGpuProcessTextureId;
125 void RegisterQuery(RefPtr<ID3D11Query> aQuery, bool aOnlyForOverlay = false);
127 private:
128 D3D11TextureData(ID3D11Texture2D* aTexture, uint32_t aArrayIndex,
129 RefPtr<gfx::FileHandleWrapper> aSharedHandle,
130 gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
131 TextureAllocationFlags aFlags);
133 bool PrepareDrawTargetInLock(OpenMode aMode);
135 friend class gl::GLBlitHelper;
136 bool SerializeSpecific(SurfaceDescriptorD3D10* aOutDesc);
138 static D3D11TextureData* Create(gfx::IntSize aSize,
139 gfx::SurfaceFormat aFormat,
140 gfx::SourceSurface* aSurface,
141 TextureAllocationFlags aAllocFlags,
142 ID3D11Device* aDevice = nullptr);
144 // Hold on to the DrawTarget because it is expensive to create one each
145 // ::Lock.
146 RefPtr<gfx::DrawTarget> mDrawTarget;
147 const gfx::IntSize mSize;
148 const gfx::SurfaceFormat mFormat;
150 public:
151 gfx::ColorSpace2 mColorSpace = gfx::ColorSpace2::SRGB;
153 private:
154 gfx::ColorRange mColorRange = gfx::ColorRange::LIMITED;
155 bool mNeedsClear = false;
156 const bool mHasKeyedMutex;
158 RefPtr<ID3D11Texture2D> mTexture;
159 const RefPtr<gfx::FileHandleWrapper> mSharedHandle;
160 Maybe<GpuProcessTextureId> mGpuProcessTextureId;
161 uint32_t mArrayIndex = 0;
162 const TextureAllocationFlags mAllocationFlags;
163 Maybe<GpuProcessQueryId> mGpuProcessQueryId;
166 class DXGIYCbCrTextureData : public TextureData {
167 friend class gl::GLBlitHelper;
169 public:
170 static DXGIYCbCrTextureData* Create(
171 ID3D11Texture2D* aTextureCb, ID3D11Texture2D* aTextureY,
172 ID3D11Texture2D* aTextureCr, const gfx::IntSize& aSize,
173 const gfx::IntSize& aSizeY, const gfx::IntSize& aSizeCbCr,
174 gfx::ColorDepth aColorDepth, gfx::YUVColorSpace aYUVColorSpace,
175 gfx::ColorRange aColorRange);
177 bool Lock(OpenMode) override { return true; }
179 void Unlock() override {}
181 void FillInfo(TextureData::Info& aInfo) const override;
183 void SerializeSpecific(SurfaceDescriptorDXGIYCbCr* aOutDesc);
184 bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
185 void GetSubDescriptor(RemoteDecoderVideoSubDescriptor* aOutDesc) override;
187 already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override {
188 return nullptr;
191 void Deallocate(LayersIPCChannel* aAllocator) override;
193 bool UpdateFromSurface(gfx::SourceSurface*) override { return false; }
195 TextureFlags GetTextureFlags() const override;
197 DXGIYCbCrTextureData* AsDXGIYCbCrTextureData() override { return this; }
199 gfx::IntSize GetYSize() const { return mSizeY; }
201 gfx::IntSize GetCbCrSize() const { return mSizeCbCr; }
203 gfx::ColorDepth GetColorDepth() const { return mColorDepth; }
204 gfx::YUVColorSpace GetYUVColorSpace() const { return mYUVColorSpace; }
205 gfx::ColorRange GetColorRange() const { return mColorRange; }
207 ID3D11Texture2D* GetD3D11Texture(size_t index) {
208 return mD3D11Textures[index];
211 protected:
212 RefPtr<ID3D11Texture2D> mD3D11Textures[3];
213 RefPtr<gfx::FileHandleWrapper> mHandles[3];
214 gfx::IntSize mSize;
215 gfx::IntSize mSizeY;
216 gfx::IntSize mSizeCbCr;
217 gfx::ColorDepth mColorDepth;
218 gfx::YUVColorSpace mYUVColorSpace;
219 gfx::ColorRange mColorRange;
223 * TextureSource that provides with the necessary APIs to be composited by a
224 * CompositorD3D11.
226 class TextureSourceD3D11 {
227 public:
228 TextureSourceD3D11() : mFormatOverride(DXGI_FORMAT_UNKNOWN) {}
229 virtual ~TextureSourceD3D11() = default;
231 virtual ID3D11Texture2D* GetD3D11Texture() const { return mTexture; }
232 virtual ID3D11ShaderResourceView* GetShaderResourceView();
234 protected:
235 virtual gfx::IntSize GetSize() const { return mSize; }
237 gfx::IntSize mSize;
238 RefPtr<ID3D11Texture2D> mTexture;
239 RefPtr<ID3D11ShaderResourceView> mSRV;
240 DXGI_FORMAT mFormatOverride;
244 * A TextureSource that implements the DataTextureSource interface.
245 * it can be used without a TextureHost and is able to upload texture data
246 * from a gfx::DataSourceSurface.
248 class DataTextureSourceD3D11 : public DataTextureSource,
249 public TextureSourceD3D11,
250 public BigImageIterator {
251 public:
252 /// Constructor allowing the texture to perform texture uploads.
254 /// The texture can be used as an actual DataTextureSource.
255 DataTextureSourceD3D11(ID3D11Device* aDevice, gfx::SurfaceFormat aFormat,
256 TextureFlags aFlags);
258 /// Constructor for textures created around DXGI shared handles, disallowing
259 /// texture uploads.
261 /// The texture CANNOT be used as a DataTextureSource.
262 DataTextureSourceD3D11(ID3D11Device* aDevice, gfx::SurfaceFormat aFormat,
263 ID3D11Texture2D* aTexture);
265 DataTextureSourceD3D11(gfx::SurfaceFormat aFormat,
266 TextureSourceProvider* aProvider,
267 ID3D11Texture2D* aTexture);
268 DataTextureSourceD3D11(gfx::SurfaceFormat aFormat,
269 TextureSourceProvider* aProvider, TextureFlags aFlags);
271 virtual ~DataTextureSourceD3D11();
273 const char* Name() const override { return "DataTextureSourceD3D11"; }
275 // DataTextureSource
277 bool Update(gfx::DataSourceSurface* aSurface,
278 nsIntRegion* aDestRegion = nullptr,
279 gfx::IntPoint* aSrcOffset = nullptr,
280 gfx::IntPoint* aDstOffset = nullptr) override;
282 // TextureSource
284 TextureSourceD3D11* AsSourceD3D11() override { return this; }
286 ID3D11Texture2D* GetD3D11Texture() const override;
288 ID3D11ShaderResourceView* GetShaderResourceView() override;
290 // Returns nullptr if this texture was created by a DXGI TextureHost.
291 DataTextureSource* AsDataTextureSource() override {
292 return mAllowTextureUploads ? this : nullptr;
295 void DeallocateDeviceData() override { mTexture = nullptr; }
297 gfx::IntSize GetSize() const override { return mSize; }
299 gfx::SurfaceFormat GetFormat() const override { return mFormat; }
301 // BigImageIterator
303 BigImageIterator* AsBigImageIterator() override {
304 return mIsTiled ? this : nullptr;
307 size_t GetTileCount() override { return mTileTextures.size(); }
309 bool NextTile() override { return (++mCurrentTile < mTileTextures.size()); }
311 gfx::IntRect GetTileRect() override;
313 void EndBigImageIteration() override { mIterating = false; }
315 void BeginBigImageIteration() override {
316 mIterating = true;
317 mCurrentTile = 0;
320 RefPtr<TextureSource> ExtractCurrentTile() override;
322 void Reset();
324 protected:
325 gfx::IntRect GetTileRect(uint32_t aIndex) const;
327 std::vector<RefPtr<ID3D11Texture2D>> mTileTextures;
328 std::vector<RefPtr<ID3D11ShaderResourceView>> mTileSRVs;
329 RefPtr<ID3D11Device> mDevice;
330 gfx::SurfaceFormat mFormat;
331 TextureFlags mFlags;
332 uint32_t mCurrentTile;
333 bool mIsTiled;
334 bool mIterating;
335 // Sadly, the code was originally organized so that this class is used both in
336 // the cases where we want to perform texture uploads through the
337 // DataTextureSource interface, and the cases where we wrap the texture around
338 // an existing DXGI handle in which case we should not use it as a
339 // DataTextureSource. This member differentiates the two scenarios. When it is
340 // false the texture "pretends" to not be a DataTextureSource.
341 bool mAllowTextureUploads;
345 * A TextureHost for shared D3D11 textures.
347 class DXGITextureHostD3D11 : public TextureHost {
348 public:
349 DXGITextureHostD3D11(TextureFlags aFlags,
350 const SurfaceDescriptorD3D10& aDescriptor);
352 void DeallocateDeviceData() override {}
354 gfx::SurfaceFormat GetFormat() const override { return mFormat; }
356 gfx::IntSize GetSize() const override { return mSize; }
357 gfx::ColorRange GetColorRange() const override { return mColorRange; }
359 already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
360 gfx::DataSourceSurface* aSurface) override;
362 // Return DataSourceSurface using aDevice withou readback to CPU.
363 already_AddRefed<gfx::DataSourceSurface> GetAsSurfaceWithDevice(
364 ID3D11Device* const aDevice,
365 DataMutex<RefPtr<VideoProcessorD3D11>>& aVideoProcessorD3D11);
367 void CreateRenderTexture(
368 const wr::ExternalImageId& aExternalImageId) override;
370 uint32_t NumSubTextures() override;
372 void PushResourceUpdates(wr::TransactionBuilder& aResources,
373 ResourceUpdateOp aOp,
374 const Range<wr::ImageKey>& aImageKeys,
375 const wr::ExternalImageId& aExtID) override;
377 void PushDisplayItems(wr::DisplayListBuilder& aBuilder,
378 const wr::LayoutRect& aBounds,
379 const wr::LayoutRect& aClip, wr::ImageRendering aFilter,
380 const Range<wr::ImageKey>& aImageKeys,
381 PushDisplayItemFlagSet aFlags) override;
383 bool SupportsExternalCompositing(WebRenderBackend aBackend) override;
385 DXGITextureHostD3D11* AsDXGITextureHostD3D11() override { return this; }
387 const RefPtr<gfx::FileHandleWrapper> mHandle;
388 const Maybe<GpuProcessTextureId> mGpuProcessTextureId;
389 const uint32_t mArrayIndex;
390 const Maybe<GpuProcessQueryId> mGpuProcessQueryId;
391 const gfx::IntSize mSize;
392 const gfx::SurfaceFormat mFormat;
393 const bool mHasKeyedMutex;
394 const gfx::FenceInfo mAcquireFenceInfo;
395 const gfx::ColorSpace2 mColorSpace;
396 const gfx::ColorRange mColorRange;
399 class DXGIYCbCrTextureHostD3D11 : public TextureHost {
400 public:
401 DXGIYCbCrTextureHostD3D11(TextureFlags aFlags,
402 const SurfaceDescriptorDXGIYCbCr& aDescriptor);
404 void DeallocateDeviceData() override {}
406 gfx::SurfaceFormat GetFormat() const override {
407 return gfx::SurfaceFormat::YUV420;
410 gfx::ColorDepth GetColorDepth() const override { return mColorDepth; }
411 gfx::YUVColorSpace GetYUVColorSpace() const override {
412 return mYUVColorSpace;
414 gfx::ColorRange GetColorRange() const override { return mColorRange; }
416 gfx::IntSize GetSize() const override { return mSize; }
418 already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
419 gfx::DataSourceSurface* aSurface) override {
420 return nullptr;
423 void CreateRenderTexture(
424 const wr::ExternalImageId& aExternalImageId) override;
426 uint32_t NumSubTextures() override;
428 void PushResourceUpdates(wr::TransactionBuilder& aResources,
429 ResourceUpdateOp aOp,
430 const Range<wr::ImageKey>& aImageKeys,
431 const wr::ExternalImageId& aExtID) override;
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;
439 bool SupportsExternalCompositing(WebRenderBackend aBackend) override;
441 protected:
442 RefPtr<ID3D11Texture2D> mTextures[3];
444 gfx::IntSize mSize;
445 gfx::IntSize mSizeY;
446 gfx::IntSize mSizeCbCr;
447 // Handles will be closed automatically when `UniqueFileHandle` gets
448 // destroyed.
449 RefPtr<gfx::FileHandleWrapper> mHandles[3];
450 bool mIsLocked;
451 gfx::ColorDepth mColorDepth;
452 gfx::YUVColorSpace mYUVColorSpace;
453 gfx::ColorRange mColorRange;
456 class CompositingRenderTargetD3D11 : public CompositingRenderTarget,
457 public TextureSourceD3D11 {
458 public:
459 CompositingRenderTargetD3D11(
460 ID3D11Texture2D* aTexture, const gfx::IntPoint& aOrigin,
461 DXGI_FORMAT aFormatOverride = DXGI_FORMAT_UNKNOWN);
463 const char* Name() const override { return "CompositingRenderTargetD3D11"; }
465 TextureSourceD3D11* AsSourceD3D11() override { return this; }
467 void BindRenderTarget(ID3D11DeviceContext* aContext);
469 gfx::IntSize GetSize() const override;
471 void SetSize(const gfx::IntSize& aSize) { mSize = aSize; }
473 private:
474 friend class CompositorD3D11;
475 RefPtr<ID3D11RenderTargetView> mRTView;
478 class SyncObjectD3D11Host : public SyncObjectHost {
479 public:
480 explicit SyncObjectD3D11Host(ID3D11Device* aDevice);
482 bool Init() override;
484 SyncHandle GetSyncHandle() override;
486 bool Synchronize(bool aFallible) override;
488 IDXGIKeyedMutex* GetKeyedMutex() { return mKeyedMutex.get(); };
490 private:
491 virtual ~SyncObjectD3D11Host() = default;
493 SyncHandle mSyncHandle;
494 RefPtr<ID3D11Device> mDevice;
495 RefPtr<IDXGIResource1> mSyncTexture;
496 RefPtr<IDXGIKeyedMutex> mKeyedMutex;
499 class SyncObjectD3D11Client : public SyncObjectClient {
500 public:
501 SyncObjectD3D11Client(SyncHandle aSyncHandle, ID3D11Device* aDevice);
503 bool Synchronize(bool aFallible) override;
505 bool IsSyncObjectValid() override;
507 void EnsureInitialized() override {}
509 SyncType GetSyncType() override { return SyncType::D3D11; }
511 void RegisterTexture(ID3D11Texture2D* aTexture);
513 protected:
514 explicit SyncObjectD3D11Client(SyncHandle aSyncHandle);
515 bool Init(ID3D11Device* aDevice, bool aFallible);
516 bool SynchronizeInternal(ID3D11Device* aDevice, bool aFallible);
517 Mutex mSyncLock MOZ_UNANNOTATED;
518 RefPtr<ID3D11Texture2D> mSyncTexture;
519 std::vector<ID3D11Texture2D*> mSyncedTextures;
521 private:
522 SyncHandle mSyncHandle;
523 RefPtr<IDXGIKeyedMutex> mKeyedMutex;
524 const RefPtr<ID3D11Device> mDevice;
527 class SyncObjectD3D11ClientContentDevice : public SyncObjectD3D11Client {
528 public:
529 explicit SyncObjectD3D11ClientContentDevice(SyncHandle aSyncHandle);
531 bool Synchronize(bool aFallible) override;
533 bool IsSyncObjectValid() override;
535 void EnsureInitialized() override;
537 private:
538 RefPtr<ID3D11Device> mContentDevice;
541 inline uint32_t GetMaxTextureSizeForFeatureLevel(
542 D3D_FEATURE_LEVEL aFeatureLevel) {
543 int32_t maxTextureSize;
544 switch (aFeatureLevel) {
545 case D3D_FEATURE_LEVEL_11_1:
546 case D3D_FEATURE_LEVEL_11_0:
547 maxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
548 break;
549 case D3D_FEATURE_LEVEL_10_1:
550 case D3D_FEATURE_LEVEL_10_0:
551 maxTextureSize = D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;
552 break;
553 case D3D_FEATURE_LEVEL_9_3:
554 maxTextureSize = D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
555 break;
556 default:
557 maxTextureSize = D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
559 return maxTextureSize;
562 uint32_t GetMaxTextureSizeFromDevice(ID3D11Device* aDevice);
563 void ReportTextureMemoryUsage(ID3D11Texture2D* aTexture, size_t aBytes);
565 class AutoLockD3D11Texture {
566 public:
567 explicit AutoLockD3D11Texture(ID3D11Texture2D* aTexture);
568 ~AutoLockD3D11Texture();
570 private:
571 RefPtr<IDXGIKeyedMutex> mMutex;
574 class D3D11MTAutoEnter {
575 public:
576 explicit D3D11MTAutoEnter(already_AddRefed<ID3D10Multithread> aMT)
577 : mMT(aMT) {
578 if (mMT) {
579 mMT->Enter();
582 ~D3D11MTAutoEnter() {
583 if (mMT) {
584 mMT->Leave();
588 private:
589 RefPtr<ID3D10Multithread> mMT;
592 } // namespace layers
593 } // namespace mozilla
595 #endif /* MOZILLA_GFX_TEXTURED3D11_H */