summaryrefslogtreecommitdiffstats
path: root/gfx/layers/d3d11/TextureHostWrapperD3D11.h
blob: dd0afc8be7ea89b392b3f495669206e430776533 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef MOZILLA_GFX_TextureHostWrapperD3D11_H
#define MOZILLA_GFX_TextureHostWrapperD3D11_H

#include <deque>
#include <unordered_map>

#include "mozilla/layers/LayersTypes.h"
#include "mozilla/layers/TextureHost.h"
#include "mozilla/UniquePtr.h"

class nsIThreadPool;
struct ID3D11Texture2D;

namespace mozilla {
namespace layers {

class DXGITextureHostD3D11;

/**
 * A Class that allocates and recycles ID3D11Texture2D in TextureUpdate thread.
 * And manages in use TextureHostWrapperD3D11s in compositor thread.
 */
class TextureWrapperD3D11Allocator {
 public:
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TextureWrapperD3D11Allocator)

  TextureWrapperD3D11Allocator();

  RefPtr<ID3D11Texture2D> CreateOrRecycle(gfx::SurfaceFormat aSurfaceFormat,
                                          gfx::IntSize aSize);

  void EnsureStagingTextureNV12(RefPtr<ID3D11Device> aDevice);

  RefPtr<ID3D11Texture2D> GetStagingTextureNV12();

  RefPtr<ID3D11Device> GetDevice();

  void RecycleTexture(RefPtr<ID3D11Texture2D>& aTexture);

  void RegisterTextureHostWrapper(const wr::ExternalImageId& aExternalImageId,
                                  RefPtr<TextureHost> aTextureHost);
  void UnregisterTextureHostWrapper(
      const wr::ExternalImageId& aExternalImageId);

  RefPtr<TextureHost> GetTextureHostWrapper(
      const wr::ExternalImageId& aExternalImageId);

  // Holds TextureUpdate thread.
  // Use the SharedThreadPool to create an nsIThreadPool with a maximum of one
  // thread, which is equivalent to an nsIThread for our purposes.
  const nsCOMPtr<nsIThreadPool> mThread;

 protected:
  ~TextureWrapperD3D11Allocator();

  void ClearAllTextures(const MutexAutoLock& aProofOfLock);

  // Holds TextureHostWrapperD3D11s that are in use. TextureHostWrapperD3D11 is
  // wrapped by WebRenderTextureHost. Accessed only from compositor thread
  std::unordered_map<uint64_t, RefPtr<TextureHost>> mTextureHostWrappers;

  // Accessed only from TextureUpdate thread
  RefPtr<ID3D11Texture2D> mStagingTexture;

  Mutex mMutex;

  // Protected by mMutex

  RefPtr<ID3D11Device> mDevice;
  gfx::IntSize mSize;
  std::deque<RefPtr<ID3D11Texture2D>> mRecycledTextures;
};

/**
 * A TextureHost that exposes DXGITextureHostD3D11 as wrapping YUV
 * BufferTextureHost. The DXGITextureHostD3D11 holds GpuProcessTextureId of
 * ID3D11Texture2D. The ID3D11Texture2D is allocated and data updated in
 * TextureUpdate thread.
 */
class TextureHostWrapperD3D11 : public TextureHost {
 public:
  static RefPtr<TextureHost> CreateFromBufferTexture(
      const RefPtr<TextureWrapperD3D11Allocator>& aAllocator,
      TextureHost* aTextureHost);

  void DeallocateDeviceData() override {}

  gfx::SurfaceFormat GetFormat() const override;

  already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override {
    return nullptr;  // XXX - implement this (for MOZ_DUMP_PAINTING)
  }

  gfx::ColorRange GetColorRange() const override;

  gfx::IntSize GetSize() const override;

  bool IsValid() override;

#ifdef MOZ_LAYERS_HAVE_LOG
  const char* Name() override { return "TextureHostWrapperD3D11"; }
#endif

  void CreateRenderTexture(
      const wr::ExternalImageId& aExternalImageId) override;

  void MaybeDestroyRenderTexture() override;

  uint32_t NumSubTextures() override;

  void PushResourceUpdates(wr::TransactionBuilder& aResources,
                           ResourceUpdateOp aOp,
                           const Range<wr::ImageKey>& aImageKeys,
                           const wr::ExternalImageId& aExtID) override;

  void PushDisplayItems(wr::DisplayListBuilder& aBuilder,
                        const wr::LayoutRect& aBounds,
                        const wr::LayoutRect& aClip, wr::ImageRendering aFilter,
                        const Range<wr::ImageKey>& aImageKeys,
                        PushDisplayItemFlagSet aFlags) override;

  bool SupportsExternalCompositing(WebRenderBackend aBackend) override;

  void UnbindTextureSource() override;

  void NotifyNotUsed() override;

  BufferTextureHost* AsBufferTextureHost() override;

  bool IsWrappingSurfaceTextureHost() override;

  TextureHostType GetTextureHostType() override;

  bool NeedsDeferredDeletion() const override;

  TextureHostWrapperD3D11* AsTextureHostWrapperD3D11() override { return this; }

  void PostTask();

  bool UpdateTextureData();

 protected:
  TextureHostWrapperD3D11(
      TextureFlags aFlags,
      const RefPtr<TextureWrapperD3D11Allocator>& aAllocator,
      const GpuProcessTextureId aTextureId,
      DXGITextureHostD3D11* aTextureHostD3D11, TextureHost* aWrappedTextureHost,
      const wr::ExternalImageId aWrappedExternalImageId);

  virtual ~TextureHostWrapperD3D11();

  TextureHost* EnsureWrappedTextureHost();

  const RefPtr<TextureWrapperD3D11Allocator> mAllocator;
  const GpuProcessTextureId mTextureId;
  // DXGITextureHostD3D11 that replaces the wrapping TextureHost.
  const RefPtr<DXGITextureHostD3D11> mTextureHostD3D11;
  // WebRenderTextureHost that wraps BufferTextureHost
  // BufferTextureHost might be further wrapped by GPUVideoTextureHost.
  CompositableTextureHostRef mWrappedTextureHost;
  const wr::ExternalImageId mWrappedExternalImageId;
};

}  // namespace layers
}  // namespace mozilla

#endif  // MOZILLA_GFX_TextureHostWrapperD3D11_H