Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set sw=2 ts=8 et 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_CompositorBridgeChild_h
8 : #define mozilla_layers_CompositorBridgeChild_h
9 :
10 : #include "base/basictypes.h" // for DISALLOW_EVIL_CONSTRUCTORS
11 : #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
12 : #include "mozilla/Attributes.h" // for override
13 : #include "mozilla/Monitor.h"
14 : #include "mozilla/ipc/ProtocolUtils.h"
15 : #include "mozilla/layers/PCompositorBridgeChild.h"
16 : #include "mozilla/layers/TextureForwarder.h" // for TextureForwarder
17 : #include "mozilla/webrender/WebRenderTypes.h"
18 : #include "nsClassHashtable.h" // for nsClassHashtable
19 : #include "nsRefPtrHashtable.h"
20 : #include "nsCOMPtr.h" // for nsCOMPtr
21 : #include "nsHashKeys.h" // for nsUint64HashKey
22 : #include "nsISupportsImpl.h" // for NS_INLINE_DECL_REFCOUNTING
23 : #include "ThreadSafeRefcountingWithMainThreadDestruction.h"
24 : #include "nsWeakReference.h"
25 :
26 : namespace mozilla {
27 :
28 : namespace dom {
29 : class TabChild;
30 : } // namespace dom
31 :
32 : namespace widget {
33 : class CompositorWidget;
34 : } // namespace widget
35 :
36 : namespace layers {
37 :
38 : using mozilla::dom::TabChild;
39 :
40 : class IAPZCTreeManager;
41 : class APZCTreeManagerChild;
42 : class ClientLayerManager;
43 : class CompositorBridgeParent;
44 : class CompositorManagerChild;
45 : class CompositorOptions;
46 : class TextureClient;
47 : class TextureClientPool;
48 : struct FrameMetrics;
49 :
50 : class CompositorBridgeChild final : public PCompositorBridgeChild,
51 : public TextureForwarder
52 : {
53 : typedef InfallibleTArray<AsyncParentMessageData> AsyncParentMessageArray;
54 :
55 : public:
56 65 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorBridgeChild, override);
57 :
58 : explicit CompositorBridgeChild(CompositorManagerChild* aManager);
59 :
60 : /**
61 : * Initialize the singleton compositor bridge for a content process.
62 : */
63 : void InitForContent(uint32_t aNamespace);
64 :
65 : void InitForWidget(uint64_t aProcessToken,
66 : LayerManager* aLayerManager,
67 : uint32_t aNamespace);
68 :
69 : void Destroy();
70 :
71 : /**
72 : * Lookup the FrameMetrics shared by the compositor process with the
73 : * associated FrameMetrics::ViewID. The returned FrameMetrics is used
74 : * in progressive paint calculations.
75 : */
76 : bool LookupCompositorFrameMetrics(const FrameMetrics::ViewID aId, FrameMetrics&);
77 :
78 : static CompositorBridgeChild* Get();
79 :
80 : static bool ChildProcessHasCompositorBridge();
81 :
82 : // Returns whether the compositor is in the GPU process (false if in the UI
83 : // process). This may only be called on the main thread.
84 : static bool CompositorIsInGPUProcess();
85 :
86 : virtual mozilla::ipc::IPCResult
87 : RecvDidComposite(const uint64_t& aId, const uint64_t& aTransactionId,
88 : const TimeStamp& aCompositeStart,
89 : const TimeStamp& aCompositeEnd) override;
90 :
91 : virtual mozilla::ipc::IPCResult
92 : RecvInvalidateLayers(const uint64_t& aLayersId) override;
93 :
94 : virtual mozilla::ipc::IPCResult
95 : RecvUpdatePluginConfigurations(const LayoutDeviceIntPoint& aContentOffset,
96 : const LayoutDeviceIntRegion& aVisibleRegion,
97 : nsTArray<PluginWindowData>&& aPlugins) override;
98 :
99 : virtual mozilla::ipc::IPCResult
100 : RecvCaptureAllPlugins(const uintptr_t& aParentWidget) override;
101 :
102 : virtual mozilla::ipc::IPCResult
103 : RecvHideAllPlugins(const uintptr_t& aParentWidget) override;
104 :
105 : virtual PTextureChild* AllocPTextureChild(const SurfaceDescriptor& aSharedData,
106 : const LayersBackend& aLayersBackend,
107 : const TextureFlags& aFlags,
108 : const uint64_t& aId,
109 : const uint64_t& aSerial,
110 : const wr::MaybeExternalImageId& aExternalImageId) override;
111 :
112 : virtual bool DeallocPTextureChild(PTextureChild* actor) override;
113 :
114 : virtual mozilla::ipc::IPCResult
115 : RecvParentAsyncMessages(InfallibleTArray<AsyncParentMessageData>&& aMessages) override;
116 : virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
117 : LayersBackend aLayersBackend,
118 : TextureFlags aFlags,
119 : uint64_t aSerial,
120 : wr::MaybeExternalImageId& aExternalImageId,
121 : nsIEventTarget* aTarget) override;
122 :
123 : /**
124 : * Request that the parent tell us when graphics are ready on GPU.
125 : * When we get that message, we bounce it to the TabParent via
126 : * the TabChild
127 : * @param tabChild The object to bounce the note to. Non-NULL.
128 : */
129 : void RequestNotifyAfterRemotePaint(TabChild* aTabChild);
130 :
131 : void CancelNotifyAfterRemotePaint(TabChild* aTabChild);
132 :
133 : // Beware that these methods don't override their super-class equivalent (which
134 : // are not virtual), they just overload them.
135 : // All of these Send* methods just add a sanity check (that it is not too late
136 : // send a message) and forward the call to the super-class's equivalent method.
137 : // This means that it is correct to call directly the super-class methods, but
138 : // you won't get the extra safety provided here.
139 : bool SendWillClose();
140 : bool SendPause();
141 : bool SendResume();
142 : bool SendNotifyChildCreated(const uint64_t& id, CompositorOptions* aOptions);
143 : bool SendAdoptChild(const uint64_t& id);
144 : bool SendMakeSnapshot(const SurfaceDescriptor& inSnapshot, const gfx::IntRect& dirtyRect);
145 : bool SendFlushRendering();
146 : bool SendGetTileSize(int32_t* tileWidth, int32_t* tileHeight);
147 : bool SendStartFrameTimeRecording(const int32_t& bufferSize, uint32_t* startIndex);
148 : bool SendStopFrameTimeRecording(const uint32_t& startIndex, nsTArray<float>* intervals);
149 : bool SendNotifyRegionInvalidated(const nsIntRegion& region);
150 : bool SendRequestNotifyAfterRemotePaint();
151 : bool SendClearApproximatelyVisibleRegions(uint64_t aLayersId, uint32_t aPresShellId);
152 : bool SendNotifyApproximatelyVisibleRegion(const ScrollableLayerGuid& aGuid,
153 : const mozilla::CSSIntRegion& aRegion);
154 : bool SendAllPluginsCaptured();
155 : bool IsSameProcess() const override;
156 :
157 18 : virtual bool IPCOpen() const override { return mCanSend; }
158 :
159 : static void ShutDown();
160 :
161 29 : void UpdateFwdTransactionId() { ++mFwdTransactionId; }
162 28 : uint64_t GetFwdTransactionId() { return mFwdTransactionId; }
163 :
164 : /**
165 : * Hold TextureClient ref until end of usage on host side if TextureFlags::RECYCLE is set.
166 : * Host side's usage is checked via CompositableRef.
167 : */
168 : void HoldUntilCompositableRefReleasedIfNecessary(TextureClient* aClient);
169 :
170 : /**
171 : * Notify id of Texture When host side end its use. Transaction id is used to
172 : * make sure if there is no newer usage.
173 : */
174 : void NotifyNotUsed(uint64_t aTextureId, uint64_t aFwdTransactionId);
175 :
176 : virtual void CancelWaitForRecycle(uint64_t aTextureId) override;
177 :
178 : TextureClientPool* GetTexturePool(KnowsCompositor* aAllocator,
179 : gfx::SurfaceFormat aFormat,
180 : TextureFlags aFlags);
181 : void ClearTexturePool();
182 :
183 : virtual FixedSizeSmallShmemSectionAllocator* GetTileLockAllocator() override;
184 :
185 : void HandleMemoryPressure();
186 :
187 24 : virtual MessageLoop* GetMessageLoop() const override { return mMessageLoop; }
188 :
189 33 : virtual base::ProcessId GetParentPid() const override { return OtherPid(); }
190 :
191 : virtual bool AllocUnsafeShmem(size_t aSize,
192 : mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
193 : mozilla::ipc::Shmem* aShmem) override;
194 : virtual bool AllocShmem(size_t aSize,
195 : mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
196 : mozilla::ipc::Shmem* aShmem) override;
197 : virtual bool DeallocShmem(mozilla::ipc::Shmem& aShmem) override;
198 :
199 : PCompositorWidgetChild* AllocPCompositorWidgetChild(const CompositorWidgetInitData& aInitData) override;
200 : bool DeallocPCompositorWidgetChild(PCompositorWidgetChild* aActor) override;
201 :
202 : PAPZCTreeManagerChild* AllocPAPZCTreeManagerChild(const uint64_t& aLayersId) override;
203 : bool DeallocPAPZCTreeManagerChild(PAPZCTreeManagerChild* aActor) override;
204 :
205 : PAPZChild* AllocPAPZChild(const uint64_t& aLayersId) override;
206 : bool DeallocPAPZChild(PAPZChild* aActor) override;
207 :
208 : void WillEndTransaction();
209 :
210 : PWebRenderBridgeChild* AllocPWebRenderBridgeChild(const wr::PipelineId& aPipelineId,
211 : const LayoutDeviceIntSize&,
212 : TextureFactoryIdentifier*,
213 : uint32_t*) override;
214 : bool DeallocPWebRenderBridgeChild(PWebRenderBridgeChild* aActor) override;
215 :
216 1 : uint64_t DeviceResetSequenceNumber() const {
217 1 : return mDeviceResetSequenceNumber;
218 : }
219 :
220 : wr::MaybeExternalImageId GetNextExternalImageId() override;
221 :
222 : wr::PipelineId GetNextPipelineId();
223 :
224 : // Must only be called from the main thread. Notifies the CompositorBridge
225 : // that the paint thread is going to begin painting asynchronously.
226 : void NotifyBeginAsyncPaint();
227 :
228 : // Must only be called from the paint thread. Notifies the CompositorBridge
229 : // that the paint thread has finished an asynchronous paint request.
230 : void NotifyFinishedAsyncPaint();
231 :
232 : // Must only be called from the main thread. Notifies the CompoistorBridge
233 : // that a transaction is about to be sent, and if the paint thread is
234 : // currently painting, to begin delaying IPC messages.
235 : void PostponeMessagesIfAsyncPainting();
236 :
237 : // Must only be called from the main thread. Ensures that any paints from
238 : // previous frames have been flushed. The main thread blocks until the
239 : // operation completes.
240 : void FlushAsyncPaints();
241 :
242 : private:
243 : // Private destructor, to discourage deletion outside of Release():
244 : virtual ~CompositorBridgeChild();
245 :
246 : // Must only be called from the paint thread. If the main thread is delaying
247 : // IPC messages, this forwards all such delayed IPC messages to the I/O thread
248 : // and resumes IPC.
249 : void ResumeIPCAfterAsyncPaint();
250 :
251 : void AfterDestroy();
252 :
253 : virtual PLayerTransactionChild*
254 : AllocPLayerTransactionChild(const nsTArray<LayersBackend>& aBackendHints,
255 : const uint64_t& aId) override;
256 :
257 : virtual bool DeallocPLayerTransactionChild(PLayerTransactionChild *aChild) override;
258 :
259 : virtual void ActorDestroy(ActorDestroyReason aWhy) override;
260 :
261 : virtual mozilla::ipc::IPCResult RecvSharedCompositorFrameMetrics(const mozilla::ipc::SharedMemoryBasic::Handle& metrics,
262 : const CrossProcessMutexHandle& handle,
263 : const uint64_t& aLayersId,
264 : const uint32_t& aAPZCId) override;
265 :
266 : virtual mozilla::ipc::IPCResult RecvReleaseSharedCompositorFrameMetrics(const ViewID& aId,
267 : const uint32_t& aAPZCId) override;
268 :
269 : virtual mozilla::ipc::IPCResult
270 : RecvRemotePaintIsReady() override;
271 :
272 : mozilla::ipc::IPCResult RecvObserveLayerUpdate(const uint64_t& aLayersId,
273 : const uint64_t& aEpoch,
274 : const bool& aActive) override;
275 :
276 : uint64_t GetNextResourceId();
277 :
278 : // Class used to store the shared FrameMetrics, mutex, and APZCId in a hash table
279 : class SharedFrameMetricsData {
280 : public:
281 : SharedFrameMetricsData(
282 : const mozilla::ipc::SharedMemoryBasic::Handle& metrics,
283 : const CrossProcessMutexHandle& handle,
284 : const uint64_t& aLayersId,
285 : const uint32_t& aAPZCId);
286 :
287 : ~SharedFrameMetricsData();
288 :
289 : void CopyFrameMetrics(FrameMetrics* aFrame);
290 : FrameMetrics::ViewID GetViewID();
291 : uint64_t GetLayersId() const;
292 : uint32_t GetAPZCId();
293 :
294 : private:
295 : // Pointer to the class that allows access to the shared memory that contains
296 : // the shared FrameMetrics
297 : RefPtr<mozilla::ipc::SharedMemoryBasic> mBuffer;
298 : CrossProcessMutex* mMutex;
299 : uint64_t mLayersId;
300 : // Unique ID of the APZC that is sharing the FrameMetrics
301 : uint32_t mAPZCId;
302 : };
303 :
304 : RefPtr<CompositorManagerChild> mCompositorManager;
305 :
306 : RefPtr<LayerManager> mLayerManager;
307 :
308 : uint32_t mIdNamespace;
309 : uint32_t mResourceId;
310 :
311 : // When not multi-process, hold a reference to the CompositorBridgeParent to keep it
312 : // alive. This reference should be null in multi-process.
313 : RefPtr<CompositorBridgeParent> mCompositorBridgeParent;
314 :
315 : // The ViewID of the FrameMetrics is used as the key for this hash table.
316 : // While this should be safe to use since the ViewID is unique
317 : nsClassHashtable<nsUint64HashKey, SharedFrameMetricsData> mFrameMetricsTable;
318 :
319 : // Weakly hold the TabChild that made a request to be alerted when
320 : // the transaction has been received.
321 : nsWeakPtr mWeakTabChild; // type is TabChild
322 :
323 : DISALLOW_EVIL_CONSTRUCTORS(CompositorBridgeChild);
324 :
325 : // True until the beginning of the two-step shutdown sequence of this actor.
326 : bool mCanSend;
327 :
328 : // False until the actor is destroyed.
329 : bool mActorDestroyed;
330 :
331 : /**
332 : * Transaction id of ShadowLayerForwarder.
333 : * It is incrementaed by UpdateFwdTransactionId() in each BeginTransaction() call.
334 : */
335 : uint64_t mFwdTransactionId;
336 :
337 : /**
338 : * Last sequence number recognized for a device reset.
339 : */
340 : uint64_t mDeviceResetSequenceNumber;
341 :
342 : /**
343 : * Hold TextureClients refs until end of their usages on host side.
344 : * It defer calling of TextureClient recycle callback.
345 : */
346 : nsRefPtrHashtable<nsUint64HashKey, TextureClient> mTexturesWaitingRecycled;
347 :
348 : MessageLoop* mMessageLoop;
349 :
350 : AutoTArray<RefPtr<TextureClientPool>,2> mTexturePools;
351 :
352 : uint64_t mProcessToken;
353 :
354 : FixedSizeSmallShmemSectionAllocator* mSectionAllocator;
355 :
356 : // Off-Main-Thread Painting state. This covers access to the OMTP-related
357 : // state below.
358 : Monitor mPaintLock;
359 :
360 : // Contains the number of outstanding asynchronous paints tied to a
361 : // PLayerTransaction on this bridge. This is R/W on both the main and paint
362 : // threads, and must be accessed within the paint lock.
363 : size_t mOutstandingAsyncPaints;
364 :
365 : // True if this CompositorBridge is currently delaying its messages until the
366 : // paint thread completes. This is R/W on both the main and paint threads, and
367 : // must be accessed within the paint lock.
368 : bool mIsWaitingForPaint;
369 : };
370 :
371 : } // namespace layers
372 : } // namespace mozilla
373 :
374 : #endif // mozilla_layers_CompositorBrigedChild_h
|