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_layers_WebRenderBridgeChild_h
8 #define mozilla_layers_WebRenderBridgeChild_h
9 
10 #include "mozilla/layers/CompositableForwarder.h"
11 #include "mozilla/layers/PWebRenderBridgeChild.h"
12 
13 namespace mozilla {
14 
15 namespace widget {
16 class CompositorWidget;
17 }
18 
19 namespace wr {
20 class DisplayListBuilder;
21 class ResourceUpdateQueue;
22 class IpcResourceUpdateQueue;
23 }  // namespace wr
24 
25 namespace layers {
26 
27 class CompositableClient;
28 class CompositorBridgeChild;
29 class StackingContextHelper;
30 class TextureForwarder;
31 class WebRenderLayerManager;
32 
33 template <class T>
34 class ThreadSafeWeakPtrHashKey : public PLDHashEntryHdr {
35  public:
36   typedef RefPtr<T> KeyType;
37   typedef const T* KeyTypePointer;
38 
ThreadSafeWeakPtrHashKey(KeyTypePointer aKey)39   explicit ThreadSafeWeakPtrHashKey(KeyTypePointer aKey)
40       : mKey(do_AddRef(const_cast<T*>(aKey))) {}
41 
GetKey()42   KeyType GetKey() const { return do_AddRef(mKey); }
KeyEquals(KeyTypePointer aKey)43   bool KeyEquals(KeyTypePointer aKey) const { return mKey == aKey; }
44 
KeyToPointer(const KeyType & aKey)45   static KeyTypePointer KeyToPointer(const KeyType& aKey) { return aKey.get(); }
HashKey(KeyTypePointer aKey)46   static PLDHashNumber HashKey(KeyTypePointer aKey) {
47     return NS_PTR_TO_UINT32(aKey) >> 2;
48   }
49   enum { ALLOW_MEMMOVE = true };
50 
51  private:
52   ThreadSafeWeakPtr<T> mKey;
53 };
54 
55 typedef ThreadSafeWeakPtrHashKey<gfx::UnscaledFont> UnscaledFontHashKey;
56 typedef ThreadSafeWeakPtrHashKey<gfx::ScaledFont> ScaledFontHashKey;
57 
58 class WebRenderBridgeChild final : public PWebRenderBridgeChild,
59                                    public CompositableForwarder {
60   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebRenderBridgeChild, override)
61 
62  public:
63   explicit WebRenderBridgeChild(const wr::PipelineId& aPipelineId);
64 
65   void AddWebRenderParentCommand(const WebRenderParentCommand& aCmd);
66   void AddWebRenderParentCommands(
67       const nsTArray<WebRenderParentCommand>& aCommands);
68 
69   void UpdateResources(wr::IpcResourceUpdateQueue& aResources);
70   void BeginTransaction();
71   void EndTransaction(const wr::LayoutSize& aContentSize,
72                       wr::BuiltDisplayList& dl,
73                       wr::IpcResourceUpdateQueue& aResources,
74                       const gfx::IntSize& aSize, uint64_t aTransactionId,
75                       const WebRenderScrollData& aScrollData,
76                       const mozilla::TimeStamp& aTxnStartTime);
77   void EndEmptyTransaction(const FocusTarget& aFocusTarget,
78                            uint64_t aTransactionId,
79                            const mozilla::TimeStamp& aTxnStartTime);
80   void ProcessWebRenderParentCommands();
81 
82   CompositorBridgeChild* GetCompositorBridgeChild();
83 
GetPipeline()84   wr::PipelineId GetPipeline() { return mPipelineId; }
85 
86   // KnowsCompositor
87   TextureForwarder* GetTextureForwarder() override;
88   LayersIPCActor* GetLayersIPCActor() override;
89   void SyncWithCompositor() override;
GetActiveResourceTracker()90   ActiveResourceTracker* GetActiveResourceTracker() override {
91     return mActiveResourceTracker.get();
92   }
93 
94   void AddPipelineIdForAsyncCompositable(const wr::PipelineId& aPipelineId,
95                                          const CompositableHandle& aHandlee);
96   void AddPipelineIdForCompositable(const wr::PipelineId& aPipelineId,
97                                     const CompositableHandle& aHandlee);
98   void RemovePipelineIdForCompositable(const wr::PipelineId& aPipelineId);
99 
100   wr::ExternalImageId AllocExternalImageIdForCompositable(
101       CompositableClient* aCompositable);
102   void DeallocExternalImageId(const wr::ExternalImageId& aImageId);
103 
104   /**
105    * Clean this up, finishing with SendShutDown() which will cause __delete__
106    * to be sent from the parent side.
107    */
108   void Destroy(bool aIsSync);
IPCOpen()109   bool IPCOpen() const { return mIPCOpen && !mDestroyed; }
IsDestroyed()110   bool IsDestroyed() const { return mDestroyed; }
111 
GetNextResourceId()112   uint32_t GetNextResourceId() { return ++mResourceId; }
GetNamespace()113   wr::IdNamespace GetNamespace() { return mIdNamespace; }
SetNamespace(wr::IdNamespace aIdNamespace)114   void SetNamespace(wr::IdNamespace aIdNamespace) {
115     mIdNamespace = aIdNamespace;
116   }
117 
GetNextFontKey()118   wr::FontKey GetNextFontKey() {
119     return wr::FontKey{GetNamespace(), GetNextResourceId()};
120   }
121 
GetNextFontInstanceKey()122   wr::FontInstanceKey GetNextFontInstanceKey() {
123     return wr::FontInstanceKey{GetNamespace(), GetNextResourceId()};
124   }
125 
GetNextImageKey()126   wr::WrImageKey GetNextImageKey() {
127     return wr::WrImageKey{GetNamespace(), GetNextResourceId()};
128   }
129 
130   void PushGlyphs(wr::DisplayListBuilder& aBuilder,
131                   Range<const wr::GlyphInstance> aGlyphs,
132                   gfx::ScaledFont* aFont, const wr::ColorF& aColor,
133                   const StackingContextHelper& aSc,
134                   const wr::LayerRect& aBounds, const wr::LayerRect& aClip,
135                   bool aBackfaceVisible,
136                   const wr::GlyphOptions* aGlyphOptions = nullptr);
137 
138   wr::FontInstanceKey GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont);
139   wr::FontKey GetFontKeyForUnscaledFont(gfx::UnscaledFont* aUnscaledFont);
140 
141   void RemoveExpiredFontKeys();
142   void ClearReadLocks();
143 
144   void BeginClearCachedResources();
145   void EndClearCachedResources();
146 
147   void SetWebRenderLayerManager(WebRenderLayerManager* aManager);
148 
149   ipc::IShmemAllocator* GetShmemAllocator();
150 
IsThreadSafe()151   virtual bool IsThreadSafe() const override { return false; }
152 
153   virtual RefPtr<KnowsCompositor> GetForMedia() override;
154 
155   /// Alloc a specific type of shmem that is intended for use in
156   /// IpcResourceUpdateQueue only, and cache at most one of them,
157   /// when called multiple times.
158   ///
159   /// Do not use this for anything else.
160   bool AllocResourceShmem(size_t aSize, RefCountedShmem& aShm);
161   /// Dealloc shared memory that was allocated with AllocResourceShmem.
162   ///
163   /// Do not use this for anything else.
164   void DeallocResourceShmem(RefCountedShmem& aShm);
165 
166   void Capture();
167 
168  private:
169   friend class CompositorBridgeChild;
170 
171   ~WebRenderBridgeChild();
172 
173   wr::ExternalImageId GetNextExternalImageId();
174 
175   // CompositableForwarder
176   void Connect(CompositableClient* aCompositable,
177                ImageContainer* aImageContainer = nullptr) override;
178   void UseTiledLayerBuffer(
179       CompositableClient* aCompositable,
180       const SurfaceDescriptorTiles& aTiledDescriptor) override;
181   void UpdateTextureRegion(CompositableClient* aCompositable,
182                            const ThebesBufferData& aThebesBufferData,
183                            const nsIntRegion& aUpdatedRegion) override;
184   void ReleaseCompositable(const CompositableHandle& aHandle) override;
185   bool DestroyInTransaction(PTextureChild* aTexture) override;
186   bool DestroyInTransaction(const CompositableHandle& aHandle);
187   void RemoveTextureFromCompositable(CompositableClient* aCompositable,
188                                      TextureClient* aTexture) override;
189   void UseTextures(CompositableClient* aCompositable,
190                    const nsTArray<TimedTextureClient>& aTextures) override;
191   void UseComponentAlphaTextures(CompositableClient* aCompositable,
192                                  TextureClient* aClientOnBlack,
193                                  TextureClient* aClientOnWhite) override;
194   void UpdateFwdTransactionId() override;
195   uint64_t GetFwdTransactionId() override;
196   bool InForwarderThread() override;
197 
198   void ActorDestroy(ActorDestroyReason why) override;
199 
200   void DoDestroy();
201 
202   mozilla::ipc::IPCResult RecvWrUpdated(
203       const wr::IdNamespace& aNewIdNamespace) override;
204 
AddIPDLReference()205   void AddIPDLReference() {
206     MOZ_ASSERT(mIPCOpen == false);
207     mIPCOpen = true;
208     AddRef();
209   }
ReleaseIPDLReference()210   void ReleaseIPDLReference() {
211     MOZ_ASSERT(mIPCOpen == true);
212     mIPCOpen = false;
213     Release();
214   }
215 
216   bool AddOpDestroy(const OpDestroy& aOp);
217 
218   nsTArray<WebRenderParentCommand> mParentCommands;
219   nsTArray<OpDestroy> mDestroyedActors;
220   nsDataHashtable<nsUint64HashKey, CompositableClient*> mCompositables;
221   nsTArray<nsTArray<ReadLockInit>> mReadLocks;
222   uint64_t mReadLockSequenceNumber;
223   bool mIsInTransaction;
224   bool mIsInClearCachedResources;
225   wr::IdNamespace mIdNamespace;
226   uint32_t mResourceId;
227   wr::PipelineId mPipelineId;
228   WebRenderLayerManager* mManager;
229 
230   bool mIPCOpen;
231   bool mDestroyed;
232 
233   uint32_t mFontKeysDeleted;
234   nsDataHashtable<UnscaledFontHashKey, wr::FontKey> mFontKeys;
235 
236   uint32_t mFontInstanceKeysDeleted;
237   nsDataHashtable<ScaledFontHashKey, wr::FontInstanceKey> mFontInstanceKeys;
238 
239   UniquePtr<ActiveResourceTracker> mActiveResourceTracker;
240 
241   RefCountedShmem mResourceShm;
242 };
243 
244 }  // namespace layers
245 }  // namespace mozilla
246 
247 #endif  // mozilla_layers_WebRenderBridgeChild_h
248