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   friend class PWebRenderBridgeChild;
63 
64  public:
65   explicit WebRenderBridgeChild(const wr::PipelineId& aPipelineId);
66 
67   void AddWebRenderParentCommand(const WebRenderParentCommand& aCmd);
HasWebRenderParentCommands()68   bool HasWebRenderParentCommands() { return !mParentCommands.IsEmpty(); }
69 
70   void UpdateResources(wr::IpcResourceUpdateQueue& aResources);
71   void BeginTransaction();
72   bool EndTransaction(DisplayListData&& aDisplayListData,
73                       TransactionId aTransactionId, bool aContainsSVGroup,
74                       const mozilla::VsyncId& aVsyncId,
75                       const mozilla::TimeStamp& aVsyncStartTime,
76                       const mozilla::TimeStamp& aRefreshStartTime,
77                       const mozilla::TimeStamp& aTxnStartTime,
78                       const nsCString& aTxtURL);
79   void EndEmptyTransaction(const FocusTarget& aFocusTarget,
80                            Maybe<TransactionData>&& aTransactionData,
81                            TransactionId aTransactionId,
82                            const mozilla::VsyncId& aVsyncId,
83                            const mozilla::TimeStamp& aVsyncStartTime,
84                            const mozilla::TimeStamp& aRefreshStartTime,
85                            const mozilla::TimeStamp& aTxnStartTime,
86                            const nsCString& aTxtURL);
87   void ProcessWebRenderParentCommands();
88 
89   CompositorBridgeChild* GetCompositorBridgeChild();
90 
GetPipeline()91   wr::PipelineId GetPipeline() { return mPipelineId; }
92 
93   // KnowsCompositor
94   TextureForwarder* GetTextureForwarder() override;
95   LayersIPCActor* GetLayersIPCActor() override;
96   void SyncWithCompositor() override;
GetActiveResourceTracker()97   ActiveResourceTracker* GetActiveResourceTracker() override {
98     return mActiveResourceTracker.get();
99   }
100 
101   void AddPipelineIdForAsyncCompositable(const wr::PipelineId& aPipelineId,
102                                          const CompositableHandle& aHandlee);
103   void AddPipelineIdForCompositable(const wr::PipelineId& aPipelineId,
104                                     const CompositableHandle& aHandlee);
105   void RemovePipelineIdForCompositable(const wr::PipelineId& aPipelineId);
106 
107   /// Release TextureClient that is bounded to ImageKey.
108   /// It is used for recycling TextureClient.
109   void ReleaseTextureOfImage(const wr::ImageKey& aKey);
110 
111   /**
112    * Clean this up, finishing with SendShutDown() which will cause __delete__
113    * to be sent from the parent side.
114    */
115   void Destroy(bool aIsSync);
IPCOpen()116   bool IPCOpen() const { return mIPCOpen && !mDestroyed; }
GetSentDisplayList()117   bool GetSentDisplayList() const { return mSentDisplayList; }
IsDestroyed()118   bool IsDestroyed() const { return mDestroyed; }
119 
GetNextResourceId()120   uint32_t GetNextResourceId() { return ++mResourceId; }
GetNamespace()121   wr::IdNamespace GetNamespace() { return mIdNamespace; }
SetNamespace(wr::IdNamespace aIdNamespace)122   void SetNamespace(wr::IdNamespace aIdNamespace) {
123     mIdNamespace = aIdNamespace;
124   }
125 
MatchesNamespace(const wr::ImageKey & aImageKey)126   bool MatchesNamespace(const wr::ImageKey& aImageKey) const {
127     return aImageKey.mNamespace == mIdNamespace;
128   }
129 
MatchesNamespace(const wr::BlobImageKey & aBlobKey)130   bool MatchesNamespace(const wr::BlobImageKey& aBlobKey) const {
131     return MatchesNamespace(aBlobKey._0);
132   }
133 
GetNextFontKey()134   wr::FontKey GetNextFontKey() {
135     return wr::FontKey{GetNamespace(), GetNextResourceId()};
136   }
137 
GetNextFontInstanceKey()138   wr::FontInstanceKey GetNextFontInstanceKey() {
139     return wr::FontInstanceKey{GetNamespace(), GetNextResourceId()};
140   }
141 
GetNextImageKey()142   wr::WrImageKey GetNextImageKey() {
143     return wr::WrImageKey{GetNamespace(), GetNextResourceId()};
144   }
145 
146   void PushGlyphs(wr::DisplayListBuilder& aBuilder,
147                   Range<const wr::GlyphInstance> aGlyphs,
148                   gfx::ScaledFont* aFont, const wr::ColorF& aColor,
149                   const StackingContextHelper& aSc,
150                   const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip,
151                   bool aBackfaceVisible,
152                   const wr::GlyphOptions* aGlyphOptions = nullptr);
153 
154   Maybe<wr::FontInstanceKey> GetFontKeyForScaledFont(
155       gfx::ScaledFont* aScaledFont,
156       wr::IpcResourceUpdateQueue* aResources = nullptr);
157   Maybe<wr::FontKey> GetFontKeyForUnscaledFont(
158       gfx::UnscaledFont* aUnscaledFont,
159       wr::IpcResourceUpdateQueue* aResources = nullptr);
160   void RemoveExpiredFontKeys(wr::IpcResourceUpdateQueue& aResources);
161 
162   void BeginClearCachedResources();
163   void EndClearCachedResources();
164 
165   void SetWebRenderLayerManager(WebRenderLayerManager* aManager);
166 
167   mozilla::ipc::IShmemAllocator* GetShmemAllocator();
168 
IsThreadSafe()169   bool IsThreadSafe() const override { return false; }
170 
171   RefPtr<KnowsCompositor> GetForMedia() override;
172 
173   /// Alloc a specific type of shmem that is intended for use in
174   /// IpcResourceUpdateQueue only, and cache at most one of them,
175   /// when called multiple times.
176   ///
177   /// Do not use this for anything else.
178   bool AllocResourceShmem(size_t aSize, RefCountedShmem& aShm);
179   /// Dealloc shared memory that was allocated with AllocResourceShmem.
180   ///
181   /// Do not use this for anything else.
182   void DeallocResourceShmem(RefCountedShmem& aShm);
183 
184   void Capture();
185   void StartCaptureSequence(const nsCString& path, uint32_t aFlags);
186   void StopCaptureSequence();
187 
188  private:
189   friend class CompositorBridgeChild;
190 
191   ~WebRenderBridgeChild();
192 
193   wr::ExternalImageId GetNextExternalImageId();
194 
195   // CompositableForwarder
196   void Connect(CompositableClient* aCompositable,
197                ImageContainer* aImageContainer = nullptr) override;
198   void UseTiledLayerBuffer(
199       CompositableClient* aCompositable,
200       const SurfaceDescriptorTiles& aTiledDescriptor) override;
201   void UpdateTextureRegion(CompositableClient* aCompositable,
202                            const ThebesBufferData& aThebesBufferData,
203                            const nsIntRegion& aUpdatedRegion) override;
204   void ReleaseCompositable(const CompositableHandle& aHandle) override;
205   bool DestroyInTransaction(PTextureChild* aTexture) override;
206   bool DestroyInTransaction(const CompositableHandle& aHandle);
207   void RemoveTextureFromCompositable(CompositableClient* aCompositable,
208                                      TextureClient* aTexture) override;
209   void UseTextures(CompositableClient* aCompositable,
210                    const nsTArray<TimedTextureClient>& aTextures) override;
211   void UseComponentAlphaTextures(CompositableClient* aCompositable,
212                                  TextureClient* aClientOnBlack,
213                                  TextureClient* aClientOnWhite) override;
214   void UpdateFwdTransactionId() override;
215   uint64_t GetFwdTransactionId() override;
216   bool InForwarderThread() override;
217 
218   void ActorDestroy(ActorDestroyReason why) override;
219 
220   void DoDestroy();
221 
222   mozilla::ipc::IPCResult RecvWrUpdated(
223       const wr::IdNamespace& aNewIdNamespace,
224       const TextureFactoryIdentifier& textureFactoryIdentifier);
225   mozilla::ipc::IPCResult RecvWrReleasedImages(
226       nsTArray<wr::ExternalImageKeyPair>&& aPairs);
227 
AddIPDLReference()228   void AddIPDLReference() {
229     MOZ_ASSERT(mIPCOpen == false);
230     mIPCOpen = true;
231     AddRef();
232   }
ReleaseIPDLReference()233   void ReleaseIPDLReference() {
234     MOZ_ASSERT(mIPCOpen == true);
235     mIPCOpen = false;
236     Release();
237   }
238 
239   bool AddOpDestroy(const OpDestroy& aOp);
240 
241   nsTArray<OpDestroy> mDestroyedActors;
242   nsTArray<WebRenderParentCommand> mParentCommands;
243   nsTHashMap<nsUint64HashKey, CompositableClient*> mCompositables;
244   bool mIsInTransaction;
245   bool mIsInClearCachedResources;
246   wr::IdNamespace mIdNamespace;
247   uint32_t mResourceId;
248   wr::PipelineId mPipelineId;
249   WebRenderLayerManager* mManager;
250 
251   bool mIPCOpen;
252   bool mDestroyed;
253   // True iff we have called SendSetDisplayList and haven't called
254   // SendClearCachedResources since that call.
255   bool mSentDisplayList;
256 
257   uint32_t mFontKeysDeleted;
258   nsTHashMap<UnscaledFontHashKey, wr::FontKey> mFontKeys;
259 
260   uint32_t mFontInstanceKeysDeleted;
261   nsTHashMap<ScaledFontHashKey, wr::FontInstanceKey> mFontInstanceKeys;
262 
263   UniquePtr<ActiveResourceTracker> mActiveResourceTracker;
264 
265   RefCountedShmem mResourceShm;
266 };
267 
268 }  // namespace layers
269 }  // namespace mozilla
270 
271 #endif  // mozilla_layers_WebRenderBridgeChild_h
272