summaryrefslogtreecommitdiffstats
path: root/gfx/layers/wr/WebRenderBridgeChild.h
blob: 2bd8dc8570d9ed2fd79bf6a119f0937c7c726726 (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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/* -*- 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_layers_WebRenderBridgeChild_h
#define mozilla_layers_WebRenderBridgeChild_h

#include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/layers/PWebRenderBridgeChild.h"

namespace mozilla {

namespace widget {
class CompositorWidget;
}

namespace wr {
class DisplayListBuilder;
class ResourceUpdateQueue;
class IpcResourceUpdateQueue;
}  // namespace wr

namespace layers {

class CompositableClient;
class CompositorBridgeChild;
class StackingContextHelper;
class TextureForwarder;
class WebRenderLayerManager;

template <class T>
class ThreadSafeWeakPtrHashKey : public PLDHashEntryHdr {
 public:
  typedef RefPtr<T> KeyType;
  typedef const T* KeyTypePointer;

  explicit ThreadSafeWeakPtrHashKey(KeyTypePointer aKey)
      : mKey(do_AddRef(const_cast<T*>(aKey))) {}

  KeyType GetKey() const { return do_AddRef(mKey); }
  bool KeyEquals(KeyTypePointer aKey) const { return mKey == aKey; }

  static KeyTypePointer KeyToPointer(const KeyType& aKey) { return aKey.get(); }
  static PLDHashNumber HashKey(KeyTypePointer aKey) {
    return NS_PTR_TO_UINT32(aKey) >> 2;
  }
  enum { ALLOW_MEMMOVE = true };

 private:
  ThreadSafeWeakPtr<T> mKey;
};

typedef ThreadSafeWeakPtrHashKey<gfx::UnscaledFont> UnscaledFontHashKey;
typedef ThreadSafeWeakPtrHashKey<gfx::ScaledFont> ScaledFontHashKey;

class WebRenderBridgeChild final : public PWebRenderBridgeChild,
                                   public CompositableForwarder {
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebRenderBridgeChild, override)

  friend class PWebRenderBridgeChild;

 public:
  explicit WebRenderBridgeChild(const wr::PipelineId& aPipelineId);

  void AddWebRenderParentCommand(const WebRenderParentCommand& aCmd);
  bool HasWebRenderParentCommands() { return !mParentCommands.IsEmpty(); }

  void UpdateResources(wr::IpcResourceUpdateQueue& aResources);
  void BeginTransaction();
  bool EndTransaction(DisplayListData&& aDisplayListData,
                      TransactionId aTransactionId, bool aContainsSVGroup,
                      const mozilla::VsyncId& aVsyncId,
                      const mozilla::TimeStamp& aVsyncStartTime,
                      const mozilla::TimeStamp& aRefreshStartTime,
                      const mozilla::TimeStamp& aTxnStartTime,
                      const nsCString& aTxtURL);
  void EndEmptyTransaction(const FocusTarget& aFocusTarget,
                           Maybe<TransactionData>&& aTransactionData,
                           TransactionId aTransactionId,
                           const mozilla::VsyncId& aVsyncId,
                           const mozilla::TimeStamp& aVsyncStartTime,
                           const mozilla::TimeStamp& aRefreshStartTime,
                           const mozilla::TimeStamp& aTxnStartTime,
                           const nsCString& aTxtURL);
  void ProcessWebRenderParentCommands();

  CompositorBridgeChild* GetCompositorBridgeChild();

  wr::PipelineId GetPipeline() { return mPipelineId; }

  // KnowsCompositor
  TextureForwarder* GetTextureForwarder() override;
  LayersIPCActor* GetLayersIPCActor() override;
  void SyncWithCompositor() override;
  ActiveResourceTracker* GetActiveResourceTracker() override {
    return mActiveResourceTracker.get();
  }

  void AddPipelineIdForCompositable(const wr::PipelineId& aPipelineId,
                                    const CompositableHandle& aHandle,
                                    CompositableHandleOwner aOwner);
  void RemovePipelineIdForCompositable(const wr::PipelineId& aPipelineId);

  /// Release TextureClient that is bounded to ImageKey.
  /// It is used for recycling TextureClient.
  void ReleaseTextureOfImage(const wr::ImageKey& aKey);

  /**
   * Clean this up, finishing with SendShutDown() which will cause __delete__
   * to be sent from the parent side.
   */
  void Destroy(bool aIsSync);
  bool IPCOpen() const { return mIPCOpen && !mDestroyed; }
  bool GetSentDisplayList() const { return mSentDisplayList; }
  bool IsDestroyed() const { return mDestroyed; }

  uint32_t GetNextResourceId() { return ++mResourceId; }
  wr::IdNamespace GetNamespace() { return mIdNamespace; }
  void SetNamespace(wr::IdNamespace aIdNamespace) {
    mIdNamespace = aIdNamespace;
  }

  bool MatchesNamespace(const wr::ImageKey& aImageKey) const {
    return aImageKey.mNamespace == mIdNamespace;
  }

  bool MatchesNamespace(const wr::BlobImageKey& aBlobKey) const {
    return MatchesNamespace(aBlobKey._0);
  }

  wr::FontKey GetNextFontKey() {
    return wr::FontKey{GetNamespace(), GetNextResourceId()};
  }

  wr::FontInstanceKey GetNextFontInstanceKey() {
    return wr::FontInstanceKey{GetNamespace(), GetNextResourceId()};
  }

  wr::WrImageKey GetNextImageKey() {
    return wr::WrImageKey{GetNamespace(), GetNextResourceId()};
  }

  void PushGlyphs(wr::DisplayListBuilder& aBuilder,
                  wr::IpcResourceUpdateQueue& aResources,
                  Range<const wr::GlyphInstance> aGlyphs,
                  gfx::ScaledFont* aFont, const wr::ColorF& aColor,
                  const StackingContextHelper& aSc,
                  const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip,
                  bool aBackfaceVisible,
                  const wr::GlyphOptions* aGlyphOptions = nullptr);

  Maybe<wr::FontInstanceKey> GetFontKeyForScaledFont(
      gfx::ScaledFont* aScaledFont, wr::IpcResourceUpdateQueue& aResources);
  Maybe<wr::FontKey> GetFontKeyForUnscaledFont(
      gfx::UnscaledFont* aUnscaledFont, wr::IpcResourceUpdateQueue& aResources);
  void RemoveExpiredFontKeys(wr::IpcResourceUpdateQueue& aResources);

  void BeginClearCachedResources();
  void EndClearCachedResources();

  void SetWebRenderLayerManager(WebRenderLayerManager* aManager);

  mozilla::ipc::IShmemAllocator* GetShmemAllocator();

  bool IsThreadSafe() const override { return false; }

  RefPtr<KnowsCompositor> GetForMedia() override;

  /// Alloc a specific type of shmem that is intended for use in
  /// IpcResourceUpdateQueue only, and cache at most one of them,
  /// when called multiple times.
  ///
  /// Do not use this for anything else.
  bool AllocResourceShmem(size_t aSize, RefCountedShmem& aShm);
  /// Dealloc shared memory that was allocated with AllocResourceShmem.
  ///
  /// Do not use this for anything else.
  void DeallocResourceShmem(RefCountedShmem& aShm);

  void Capture();
  void StartCaptureSequence(const nsCString& path, uint32_t aFlags);
  void StopCaptureSequence();

 private:
  friend class CompositorBridgeChild;

  ~WebRenderBridgeChild();

  wr::ExternalImageId GetNextExternalImageId();

  // CompositableForwarder
  void Connect(CompositableClient* aCompositable,
               ImageContainer* aImageContainer = nullptr) override;
  void ReleaseCompositable(const CompositableHandle& aHandle) override;
  bool DestroyInTransaction(PTextureChild* aTexture) override;
  bool DestroyInTransaction(const CompositableHandle& aHandle);
  void RemoveTextureFromCompositable(CompositableClient* aCompositable,
                                     TextureClient* aTexture) override;
  void UseTextures(CompositableClient* aCompositable,
                   const nsTArray<TimedTextureClient>& aTextures) override;
  void UseRemoteTexture(CompositableClient* aCompositable,
                        const RemoteTextureId aTextureId,
                        const RemoteTextureOwnerId aOwnerId,
                        const gfx::IntSize aSize,
                        const TextureFlags aFlags) override;
  void EnableRemoteTexturePushCallback(CompositableClient* aCompositable,
                                       const RemoteTextureOwnerId aOwnerId,
                                       const gfx::IntSize aSize,
                                       const TextureFlags aFlags) override;
  void UpdateFwdTransactionId() override;
  uint64_t GetFwdTransactionId() override;
  bool InForwarderThread() override;

  void ActorDestroy(ActorDestroyReason why) override;

  void DoDestroy();

  mozilla::ipc::IPCResult RecvWrUpdated(
      const wr::IdNamespace& aNewIdNamespace,
      const TextureFactoryIdentifier& textureFactoryIdentifier);
  mozilla::ipc::IPCResult RecvWrReleasedImages(
      nsTArray<wr::ExternalImageKeyPair>&& aPairs);

  void AddIPDLReference() {
    MOZ_ASSERT(mIPCOpen == false);
    mIPCOpen = true;
    AddRef();
  }
  void ReleaseIPDLReference() {
    MOZ_ASSERT(mIPCOpen == true);
    mIPCOpen = false;
    Release();
  }

  bool AddOpDestroy(const OpDestroy& aOp);

  nsTArray<OpDestroy> mDestroyedActors;
  nsTArray<WebRenderParentCommand> mParentCommands;
  nsTHashMap<nsUint64HashKey, CompositableClient*> mCompositables;
  bool mIsInTransaction;
  bool mIsInClearCachedResources;
  wr::IdNamespace mIdNamespace;
  uint32_t mResourceId;
  wr::PipelineId mPipelineId;
  WebRenderLayerManager* mManager;

  bool mIPCOpen;
  bool mDestroyed;
  // True iff we have called SendSetDisplayList and haven't called
  // SendClearCachedResources since that call.
  bool mSentDisplayList;

  uint32_t mFontKeysDeleted;
  nsTHashMap<UnscaledFontHashKey, wr::FontKey> mFontKeys;

  uint32_t mFontInstanceKeysDeleted;
  nsTHashMap<ScaledFontHashKey, wr::FontInstanceKey> mFontInstanceKeys;

  UniquePtr<ActiveResourceTracker> mActiveResourceTracker;

  RefCountedShmem mResourceShm;
};

}  // namespace layers
}  // namespace mozilla

#endif  // mozilla_layers_WebRenderBridgeChild_h