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_CompositorBridgeParent_h
8 #define mozilla_layers_CompositorBridgeParent_h
9
10 // Enable this pref to turn on compositor performance warning.
11 // This will print warnings if the compositor isn't meeting
12 // its responsiveness objectives:
13 // 1) Compose a frame within 15ms of receiving a ScheduleCompositeCall
14 // 2) Unless a frame was composited within the throttle threshold in
15 // which the deadline will be 15ms + throttle threshold
16 //#define COMPOSITOR_PERFORMANCE_WARNING
17
18 #include <stdint.h> // for uint64_t
19 #include "Layers.h" // for Layer
20 #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
21 #include "mozilla/Attributes.h" // for override
22 #include "mozilla/GfxMessageUtils.h" // for WebGLVersion
23 #include "mozilla/Maybe.h"
24 #include "mozilla/Monitor.h" // for Monitor
25 #include "mozilla/RefPtr.h" // for RefPtr
26 #include "mozilla/TimeStamp.h" // for TimeStamp
27 #include "mozilla/dom/ipc/IdType.h"
28 #include "mozilla/gfx/Point.h" // for IntSize
29 #include "mozilla/ipc/ProtocolUtils.h"
30 #include "mozilla/ipc/SharedMemory.h"
31 #include "mozilla/layers/CompositionRecorder.h"
32 #include "mozilla/layers/CompositorController.h"
33 #include "mozilla/layers/CompositorOptions.h"
34 #include "mozilla/layers/CompositorVsyncSchedulerOwner.h"
35 #include "mozilla/layers/ISurfaceAllocator.h" // for IShmemAllocator
36 #include "mozilla/layers/LayersMessages.h" // for TargetConfig
37 #include "mozilla/layers/MetricsSharingController.h"
38 #include "mozilla/layers/PCompositorBridgeTypes.h"
39 #include "mozilla/layers/PCompositorBridgeParent.h"
40 #include "mozilla/layers/APZTestData.h"
41 #include "mozilla/webrender/WebRenderTypes.h"
42 #include "mozilla/webrender/RenderThread.h"
43 #include "mozilla/widget/CompositorWidget.h"
44 #include "nsISupportsImpl.h"
45 #include "ThreadSafeRefcountingWithMainThreadDestruction.h"
46 #include "mozilla/layers/UiCompositorControllerParent.h"
47 #include "mozilla/VsyncDispatcher.h"
48
49 class nsIWidget;
50
51 namespace mozilla {
52
53 class CancelableRunnable;
54
55 namespace dom {
56 class WebGLParent;
57 } // namespace dom
58
59 namespace gfx {
60 class DrawTarget;
61 class GPUProcessManager;
62 class GPUParent;
63 } // namespace gfx
64
65 namespace ipc {
66 class Shmem;
67 #ifdef FUZZING
68 class ProtocolFuzzerHelper;
69 #endif
70 } // namespace ipc
71
72 namespace webgpu {
73 class PWebGPUParent;
74 class WebGPUParent;
75 } // namespace webgpu
76
77 namespace layers {
78
79 class APZCTreeManager;
80 class APZCTreeManagerParent;
81 class APZSampler;
82 class APZUpdater;
83 class AsyncCompositionManager;
84 class AsyncImagePipelineManager;
85 class Compositor;
86 class CompositorAnimationStorage;
87 class CompositorBridgeParent;
88 class CompositorManagerParent;
89 class CompositorVsyncScheduler;
90 class GeckoContentController;
91 class HostLayerManager;
92 class IAPZCTreeManager;
93 class LayerTransactionParent;
94 class PAPZParent;
95 class ContentCompositorBridgeParent;
96 class CompositorThreadHolder;
97 class InProcessCompositorSession;
98 class TextureData;
99 class WebRenderBridgeParent;
100
101 struct ScopedLayerTreeRegistration {
102 ScopedLayerTreeRegistration(APZCTreeManager* aApzctm, LayersId aLayersId,
103 Layer* aRoot,
104 GeckoContentController* aController);
105 ~ScopedLayerTreeRegistration();
106
107 private:
108 LayersId mLayersId;
109 };
110
111 class CompositorBridgeParentBase : public PCompositorBridgeParent,
112 public HostIPCAllocator,
113 public mozilla::ipc::IShmemAllocator,
114 public MetricsSharingController {
115 friend class PCompositorBridgeParent;
116
117 public:
118 explicit CompositorBridgeParentBase(CompositorManagerParent* aManager);
119
120 virtual void ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
121 const TransactionInfo& aInfo,
122 bool aHitTestUpdate) = 0;
123
GetCompositionManager(LayerTransactionParent * aLayerTree)124 virtual AsyncCompositionManager* GetCompositionManager(
125 LayerTransactionParent* aLayerTree) {
126 return nullptr;
127 }
128
NotifyClearCachedResources(LayerTransactionParent * aLayerTree)129 virtual void NotifyClearCachedResources(LayerTransactionParent* aLayerTree) {}
130
ScheduleComposite(LayerTransactionParent * aLayerTree)131 virtual void ScheduleComposite(LayerTransactionParent* aLayerTree) {}
SetTestSampleTime(const LayersId & aId,const TimeStamp & aTime)132 virtual bool SetTestSampleTime(const LayersId& aId, const TimeStamp& aTime) {
133 return true;
134 }
LeaveTestMode(const LayersId & aId)135 virtual void LeaveTestMode(const LayersId& aId) {}
136 enum class TransformsToSkip : uint8_t { NoneOfThem = 0, APZ = 1 };
137 virtual void ApplyAsyncProperties(LayerTransactionParent* aLayerTree,
138 TransformsToSkip aSkip) = 0;
139 virtual void SetTestAsyncScrollOffset(
140 const LayersId& aLayersId, const ScrollableLayerGuid::ViewID& aScrollId,
141 const CSSPoint& aPoint) = 0;
142 virtual void SetTestAsyncZoom(const LayersId& aLayersId,
143 const ScrollableLayerGuid::ViewID& aScrollId,
144 const LayerToParentLayerScale& aZoom) = 0;
145 virtual void FlushApzRepaints(const LayersId& aLayersId) = 0;
GetAPZTestData(const LayersId & aLayersId,APZTestData * aOutData)146 virtual void GetAPZTestData(const LayersId& aLayersId,
147 APZTestData* aOutData) {}
148 virtual void SetConfirmedTargetAPZC(
149 const LayersId& aLayersId, const uint64_t& aInputBlockId,
150 const nsTArray<ScrollableLayerGuid>& aTargets) = 0;
UpdatePaintTime(LayerTransactionParent * aLayerTree,const TimeDuration & aPaintTime)151 virtual void UpdatePaintTime(LayerTransactionParent* aLayerTree,
152 const TimeDuration& aPaintTime) {}
RegisterPayloads(LayerTransactionParent * aLayerTree,const nsTArray<CompositionPayload> & aPayload)153 virtual void RegisterPayloads(LayerTransactionParent* aLayerTree,
154 const nsTArray<CompositionPayload>& aPayload) {}
155
AsShmemAllocator()156 IShmemAllocator* AsShmemAllocator() override { return this; }
157
AsCompositorBridgeParentBase()158 CompositorBridgeParentBase* AsCompositorBridgeParentBase() override {
159 return this;
160 }
161
RecvSyncWithCompositor()162 mozilla::ipc::IPCResult RecvSyncWithCompositor() { return IPC_OK(); }
163
Recv__delete__()164 mozilla::ipc::IPCResult Recv__delete__() override { return IPC_OK(); }
165
166 virtual void ObserveLayersUpdate(LayersId aLayersId,
167 LayersObserverEpoch aEpoch,
168 bool aActive) = 0;
169
170 // HostIPCAllocator
171 base::ProcessId GetChildProcessId() override;
172 void NotifyNotUsed(PTextureParent* aTexture,
173 uint64_t aTransactionId) override;
174 void SendAsyncMessage(
175 const nsTArray<AsyncParentMessageData>& aMessage) override;
176
177 // IShmemAllocator
178 bool AllocShmem(size_t aSize,
179 mozilla::ipc::SharedMemory::SharedMemoryType aType,
180 mozilla::ipc::Shmem* aShmem) override;
181 bool AllocUnsafeShmem(size_t aSize,
182 mozilla::ipc::SharedMemory::SharedMemoryType aType,
183 mozilla::ipc::Shmem* aShmem) override;
184 bool DeallocShmem(mozilla::ipc::Shmem& aShmem) override;
185
186 // MetricsSharingController
AddRef()187 NS_IMETHOD_(MozExternalRefCountType) AddRef() override {
188 return HostIPCAllocator::AddRef();
189 }
Release()190 NS_IMETHOD_(MozExternalRefCountType) Release() override {
191 return HostIPCAllocator::Release();
192 }
193 base::ProcessId RemotePid() override;
194 bool StartSharingMetrics(mozilla::ipc::SharedMemoryBasic::Handle aHandle,
195 CrossProcessMutexHandle aMutexHandle,
196 LayersId aLayersId, uint32_t aApzcId) override;
197 bool StopSharingMetrics(ScrollableLayerGuid::ViewID aScrollId,
198 uint32_t aApzcId) override;
199
IsRemote()200 virtual bool IsRemote() const { return false; }
201
202 virtual UniquePtr<SurfaceDescriptor>
LookupSurfaceDescriptorForClientDrawTarget(const uintptr_t aDrawTarget)203 LookupSurfaceDescriptorForClientDrawTarget(const uintptr_t aDrawTarget) {
204 MOZ_CRASH("Should only be called on ContentCompositorBridgeParent.");
205 }
206
207 virtual void ForceComposeToTarget(gfx::DrawTarget* aTarget,
208 const gfx::IntRect* aRect = nullptr) {
209 MOZ_CRASH();
210 }
211
NotifyMemoryPressure()212 virtual void NotifyMemoryPressure() {}
AccumulateMemoryReport(wr::MemoryReport *)213 virtual void AccumulateMemoryReport(wr::MemoryReport*) {}
214
215 protected:
216 virtual ~CompositorBridgeParentBase();
217
218 virtual PAPZParent* AllocPAPZParent(const LayersId& layersId) = 0;
219 virtual bool DeallocPAPZParent(PAPZParent* aActor) = 0;
220
221 virtual PAPZCTreeManagerParent* AllocPAPZCTreeManagerParent(
222 const LayersId& layersId) = 0;
223 virtual bool DeallocPAPZCTreeManagerParent(
224 PAPZCTreeManagerParent* aActor) = 0;
225
226 virtual PLayerTransactionParent* AllocPLayerTransactionParent(
227 const nsTArray<LayersBackend>& layersBackendHints,
228 const LayersId& id) = 0;
229 virtual bool DeallocPLayerTransactionParent(
230 PLayerTransactionParent* aActor) = 0;
231
232 virtual PTextureParent* AllocPTextureParent(
233 const SurfaceDescriptor& aSharedData, const ReadLockDescriptor& aReadLock,
234 const LayersBackend& aBackend, const TextureFlags& aTextureFlags,
235 const LayersId& id, const uint64_t& aSerial,
236 const MaybeExternalImageId& aExternalImageId) = 0;
237 virtual bool DeallocPTextureParent(PTextureParent* aActor) = 0;
238
239 virtual PWebRenderBridgeParent* AllocPWebRenderBridgeParent(
240 const PipelineId& pipelineId, const LayoutDeviceIntSize& aSize) = 0;
241 virtual bool DeallocPWebRenderBridgeParent(
242 PWebRenderBridgeParent* aActor) = 0;
243
244 virtual webgpu::PWebGPUParent* AllocPWebGPUParent() = 0;
245 virtual bool DeallocPWebGPUParent(webgpu::PWebGPUParent* aActor) = 0;
246
247 virtual PCompositorWidgetParent* AllocPCompositorWidgetParent(
248 const CompositorWidgetInitData& aInitData) = 0;
249 virtual bool DeallocPCompositorWidgetParent(
250 PCompositorWidgetParent* aActor) = 0;
251
252 virtual mozilla::ipc::IPCResult RecvRemotePluginsReady() = 0;
253 virtual mozilla::ipc::IPCResult RecvAdoptChild(const LayersId& id) = 0;
254 virtual mozilla::ipc::IPCResult RecvFlushRenderingAsync() = 0;
255 virtual mozilla::ipc::IPCResult RecvForcePresent() = 0;
256 virtual mozilla::ipc::IPCResult RecvNotifyRegionInvalidated(
257 const nsIntRegion& region) = 0;
258 virtual mozilla::ipc::IPCResult RecvRequestNotifyAfterRemotePaint() = 0;
259 virtual mozilla::ipc::IPCResult RecvAllPluginsCaptured() = 0;
260 virtual mozilla::ipc::IPCResult RecvBeginRecording(
261 const TimeStamp& aRecordingStart, BeginRecordingResolver&& aResolve) = 0;
262 virtual mozilla::ipc::IPCResult RecvEndRecordingToDisk(
263 EndRecordingToDiskResolver&& aResolve) = 0;
264 virtual mozilla::ipc::IPCResult RecvEndRecordingToMemory(
265 EndRecordingToMemoryResolver&& aResolve) = 0;
266 virtual mozilla::ipc::IPCResult RecvInitialize(
267 const LayersId& rootLayerTreeId) = 0;
268 virtual mozilla::ipc::IPCResult RecvGetFrameUniformity(
269 FrameUniformityData* data) = 0;
270 virtual mozilla::ipc::IPCResult RecvWillClose() = 0;
271 virtual mozilla::ipc::IPCResult RecvPause() = 0;
272 virtual mozilla::ipc::IPCResult RecvRequestFxrOutput() = 0;
273 virtual mozilla::ipc::IPCResult RecvResume() = 0;
274 virtual mozilla::ipc::IPCResult RecvResumeAsync() = 0;
275 virtual mozilla::ipc::IPCResult RecvNotifyChildCreated(
276 const LayersId& id, CompositorOptions* compositorOptions) = 0;
277 virtual mozilla::ipc::IPCResult RecvMapAndNotifyChildCreated(
278 const LayersId& id, const ProcessId& owner,
279 CompositorOptions* compositorOptions) = 0;
280 virtual mozilla::ipc::IPCResult RecvNotifyChildRecreated(
281 const LayersId& id, CompositorOptions* compositorOptions) = 0;
282 virtual mozilla::ipc::IPCResult RecvMakeSnapshot(
283 const SurfaceDescriptor& inSnapshot, const IntRect& dirtyRect) = 0;
284 virtual mozilla::ipc::IPCResult RecvFlushRendering() = 0;
285 virtual mozilla::ipc::IPCResult RecvWaitOnTransactionProcessed() = 0;
286 virtual mozilla::ipc::IPCResult RecvStartFrameTimeRecording(
287 const int32_t& bufferSize, uint32_t* startIndex) = 0;
288 virtual mozilla::ipc::IPCResult RecvStopFrameTimeRecording(
289 const uint32_t& startIndex, nsTArray<float>* intervals) = 0;
290 virtual mozilla::ipc::IPCResult RecvCheckContentOnlyTDR(
291 const uint32_t& sequenceNum, bool* isContentOnlyTDR) = 0;
292 virtual mozilla::ipc::IPCResult RecvInitPCanvasParent(
293 Endpoint<PCanvasParent>&& aEndpoint) = 0;
294 virtual mozilla::ipc::IPCResult RecvReleasePCanvasParent() = 0;
295
RecvSupportsAsyncDXGISurface(bool * value)296 virtual mozilla::ipc::IPCResult RecvSupportsAsyncDXGISurface(bool* value) {
297 return IPC_FAIL_NO_REASON(this);
298 }
RecvPreferredDXGIAdapter(DxgiAdapterDesc * desc)299 virtual mozilla::ipc::IPCResult RecvPreferredDXGIAdapter(
300 DxgiAdapterDesc* desc) {
301 return IPC_FAIL_NO_REASON(this);
302 }
303
304 virtual already_AddRefed<PWebGLParent> AllocPWebGLParent() = 0;
305
306 bool mCanSend;
307
308 private:
309 RefPtr<CompositorManagerParent> mCompositorManager;
310 };
311
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CompositorBridgeParentBase::TransformsToSkip)312 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(
313 CompositorBridgeParentBase::TransformsToSkip)
314
315 class CompositorBridgeParent final : public CompositorBridgeParentBase,
316 public CompositorController,
317 public CompositorVsyncSchedulerOwner {
318 friend class CompositorThreadHolder;
319 friend class InProcessCompositorSession;
320 friend class gfx::GPUProcessManager;
321 friend class gfx::GPUParent;
322 friend class PCompositorBridgeParent;
323 #ifdef FUZZING
324 friend class mozilla::ipc::ProtocolFuzzerHelper;
325 #endif
326
327 public:
328 NS_IMETHOD_(MozExternalRefCountType) AddRef() override {
329 return CompositorBridgeParentBase::AddRef();
330 }
331 NS_IMETHOD_(MozExternalRefCountType) Release() override {
332 return CompositorBridgeParentBase::Release();
333 }
334
335 explicit CompositorBridgeParent(CompositorManagerParent* aManager,
336 CSSToLayoutDeviceScale aScale,
337 const TimeDuration& aVsyncRate,
338 const CompositorOptions& aOptions,
339 bool aUseExternalSurfaceSize,
340 const gfx::IntSize& aSurfaceSize);
341
342 void InitSameProcess(widget::CompositorWidget* aWidget,
343 const LayersId& aLayerTreeId);
344
345 mozilla::ipc::IPCResult RecvInitialize(
346 const LayersId& aRootLayerTreeId) override;
347 mozilla::ipc::IPCResult RecvGetFrameUniformity(
348 FrameUniformityData* aOutData) override;
349 mozilla::ipc::IPCResult RecvWillClose() override;
350 mozilla::ipc::IPCResult RecvPause() override;
351 mozilla::ipc::IPCResult RecvRequestFxrOutput() override;
352 mozilla::ipc::IPCResult RecvResume() override;
353 mozilla::ipc::IPCResult RecvResumeAsync() override;
354 mozilla::ipc::IPCResult RecvNotifyChildCreated(
355 const LayersId& child, CompositorOptions* aOptions) override;
356 mozilla::ipc::IPCResult RecvMapAndNotifyChildCreated(
357 const LayersId& child, const base::ProcessId& pid,
358 CompositorOptions* aOptions) override;
359 mozilla::ipc::IPCResult RecvNotifyChildRecreated(
360 const LayersId& child, CompositorOptions* aOptions) override;
361 mozilla::ipc::IPCResult RecvAdoptChild(const LayersId& child) override;
362 mozilla::ipc::IPCResult RecvMakeSnapshot(const SurfaceDescriptor& aInSnapshot,
363 const gfx::IntRect& aRect) override;
364 mozilla::ipc::IPCResult RecvFlushRendering() override;
365 mozilla::ipc::IPCResult RecvFlushRenderingAsync() override;
366 mozilla::ipc::IPCResult RecvWaitOnTransactionProcessed() override;
367 mozilla::ipc::IPCResult RecvForcePresent() override;
368
369 mozilla::ipc::IPCResult RecvNotifyRegionInvalidated(
370 const nsIntRegion& aRegion) override;
371 mozilla::ipc::IPCResult RecvStartFrameTimeRecording(
372 const int32_t& aBufferSize, uint32_t* aOutStartIndex) override;
373 mozilla::ipc::IPCResult RecvStopFrameTimeRecording(
374 const uint32_t& aStartIndex, nsTArray<float>* intervals) override;
375
376 mozilla::ipc::IPCResult RecvCheckContentOnlyTDR(
377 const uint32_t& sequenceNum, bool* isContentOnlyTDR) override {
378 return IPC_OK();
379 }
380
381 // Unused for chrome <-> compositor communication (which this class does).
382 // @see ContentCompositorBridgeParent::RecvRequestNotifyAfterRemotePaint
383 mozilla::ipc::IPCResult RecvRequestNotifyAfterRemotePaint() override {
384 return IPC_OK();
385 };
386
387 mozilla::ipc::IPCResult RecvAllPluginsCaptured() override;
388 mozilla::ipc::IPCResult RecvBeginRecording(
389 const TimeStamp& aRecordingStart,
390 BeginRecordingResolver&& aResolve) override;
391 mozilla::ipc::IPCResult RecvEndRecordingToDisk(
392 EndRecordingToDiskResolver&& aResolve) override;
393 mozilla::ipc::IPCResult RecvEndRecordingToMemory(
394 EndRecordingToMemoryResolver&& aResolve) override;
395
396 void NotifyMemoryPressure() override;
397 void AccumulateMemoryReport(wr::MemoryReport*) override;
398
399 void ActorDestroy(ActorDestroyReason why) override;
400
401 void ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
402 const TransactionInfo& aInfo,
403 bool aHitTestUpdate) override;
404 void ScheduleComposite(LayerTransactionParent* aLayerTree) override;
405 bool SetTestSampleTime(const LayersId& aId, const TimeStamp& aTime) override;
406 void LeaveTestMode(const LayersId& aId) override;
407 void ApplyAsyncProperties(LayerTransactionParent* aLayerTree,
408 TransformsToSkip aSkip) override;
409 CompositorAnimationStorage* GetAnimationStorage();
410 void SetTestAsyncScrollOffset(const LayersId& aLayersId,
411 const ScrollableLayerGuid::ViewID& aScrollId,
412 const CSSPoint& aPoint) override;
413 void SetTestAsyncZoom(const LayersId& aLayersId,
414 const ScrollableLayerGuid::ViewID& aScrollId,
415 const LayerToParentLayerScale& aZoom) override;
416 void FlushApzRepaints(const LayersId& aLayersId) override;
417 void GetAPZTestData(const LayersId& aLayersId,
418 APZTestData* aOutData) override;
419 void SetConfirmedTargetAPZC(
420 const LayersId& aLayersId, const uint64_t& aInputBlockId,
421 const nsTArray<ScrollableLayerGuid>& aTargets) override;
422 AsyncCompositionManager* GetCompositionManager(
423 LayerTransactionParent* aLayerTree) override {
424 return mCompositionManager;
425 }
426 void SetFixedLayerMargins(ScreenIntCoord aTop, ScreenIntCoord aBottom);
427
428 PTextureParent* AllocPTextureParent(
429 const SurfaceDescriptor& aSharedData, const ReadLockDescriptor& aReadLock,
430 const LayersBackend& aLayersBackend, const TextureFlags& aFlags,
431 const LayersId& aId, const uint64_t& aSerial,
432 const wr::MaybeExternalImageId& aExternalImageId) override;
433 bool DeallocPTextureParent(PTextureParent* actor) override;
434
435 mozilla::ipc::IPCResult RecvInitPCanvasParent(
436 Endpoint<PCanvasParent>&& aEndpoint) final;
437
438 mozilla::ipc::IPCResult RecvReleasePCanvasParent() final;
439
440 bool IsSameProcess() const override;
441
442 void NotifyWebRenderContextPurge();
443 void NotifyWebRenderDisableNativeCompositor();
444
445 void NotifyPipelineRendered(const wr::PipelineId& aPipelineId,
446 const wr::Epoch& aEpoch,
447 const VsyncId& aCompositeStartId,
448 TimeStamp& aCompositeStart,
449 TimeStamp& aRenderStart, TimeStamp& aCompositeEnd,
450 wr::RendererStats* aStats = nullptr);
451 void NotifyDidSceneBuild(RefPtr<const wr::WebRenderPipelineInfo> aInfo);
452 RefPtr<AsyncImagePipelineManager> GetAsyncImagePipelineManager() const;
453
454 PCompositorWidgetParent* AllocPCompositorWidgetParent(
455 const CompositorWidgetInitData& aInitData) override;
456 bool DeallocPCompositorWidgetParent(PCompositorWidgetParent* aActor) override;
457
458 void ObserveLayersUpdate(LayersId aLayersId, LayersObserverEpoch aEpoch,
459 bool aActive) override {}
460
461 /**
462 * This forces the is-first-paint flag to true. This is intended to
463 * be called by the widget code when it loses its viewport information
464 * (or for whatever reason wants to refresh the viewport information).
465 * The information refresh happens because the compositor will call
466 * SetFirstPaintViewport on the next frame of composition.
467 */
468 void ForceIsFirstPaint();
469
470 static void SetShadowProperties(Layer* aLayer);
471
472 void NotifyChildCreated(LayersId aChild);
473
474 void AsyncRender();
475
476 // Can be called from any thread
477 void ScheduleRenderOnCompositorThread() override;
478 void SchedulePauseOnCompositorThread();
479 void InvalidateOnCompositorThread();
480 /**
481 * Returns true if a surface was obtained and the resume succeeded; false
482 * otherwise.
483 */
484 bool ScheduleResumeOnCompositorThread();
485 bool ScheduleResumeOnCompositorThread(int x, int y, int width, int height);
486
487 void ScheduleComposition();
488
489 void NotifyShadowTreeTransaction(LayersId aId, bool aIsFirstPaint,
490 const FocusTarget& aFocusTarget,
491 bool aScheduleComposite,
492 uint32_t aPaintSequenceNumber,
493 bool aIsRepeatTransaction,
494 bool aHitTestUpdate);
495
496 void UpdatePaintTime(LayerTransactionParent* aLayerTree,
497 const TimeDuration& aPaintTime) override;
498 void RegisterPayloads(LayerTransactionParent* aLayerTree,
499 const nsTArray<CompositionPayload>& aPayload) override;
500
501 /**
502 * Check rotation info and schedule a rendering task if needed.
503 * Only can be called from compositor thread.
504 */
505 void ScheduleRotationOnCompositorThread(const TargetConfig& aTargetConfig,
506 bool aIsFirstPaint);
507
508 static void ScheduleForcedComposition(const LayersId& aLayersId);
509
510 /**
511 * Returns the unique layer tree identifier that corresponds to the root
512 * tree of this compositor.
513 */
514 LayersId RootLayerTreeId();
515
516 /**
517 * Notify local and remote layer trees connected to this compositor that
518 * the compositor's local device is being reset. All layers must be
519 * invalidated to clear any cached TextureSources.
520 *
521 * This must be called on the compositor thread.
522 */
523 void InvalidateRemoteLayers();
524
525 /**
526 * Initialize statics.
527 */
528 static void InitializeStatics();
529
530 /**
531 * Returns a pointer to the CompositorBridgeParent corresponding to the given
532 * ID.
533 */
534 static CompositorBridgeParent* GetCompositorBridgeParent(uint64_t id);
535
536 /**
537 * Notify the compositor for the given layer tree that vsync has occurred.
538 */
539 static void NotifyVsync(const VsyncEvent& aVsync, const LayersId& aLayersId);
540
541 /**
542 * Set aController as the pan/zoom callback for the subtree referred
543 * to by aLayersId.
544 *
545 * Must run on content main thread.
546 */
547 static void SetControllerForLayerTree(LayersId aLayersId,
548 GeckoContentController* aController);
549
550 struct LayerTreeState {
551 LayerTreeState();
552 ~LayerTreeState();
553 RefPtr<Layer> mRoot;
554 RefPtr<GeckoContentController> mController;
555 APZCTreeManagerParent* mApzcTreeManagerParent;
556 RefPtr<CompositorBridgeParent> mParent;
557 HostLayerManager* mLayerManager;
558 RefPtr<WebRenderBridgeParent> mWrBridge;
559 // Pointer to the ContentCompositorBridgeParent. Used by APZCs to share
560 // their FrameMetrics with the corresponding child process that holds
561 // the PCompositorBridgeChild
562 ContentCompositorBridgeParent* mContentCompositorBridgeParent;
563 TargetConfig mTargetConfig;
564 LayerTransactionParent* mLayerTree;
565 nsTArray<PluginWindowData> mPluginData;
566 bool mUpdatedPluginDataAvailable;
567
568 CompositorController* GetCompositorController() const;
569 MetricsSharingController* CrossProcessSharingController() const;
570 MetricsSharingController* InProcessSharingController() const;
571 RefPtr<UiCompositorControllerParent> mUiControllerParent;
572 };
573
574 /**
575 * Lookup the indirect shadow tree for |aId| and return it if it
576 * exists. Otherwise null is returned. This must only be called on
577 * the compositor thread.
578 */
579 static LayerTreeState* GetIndirectShadowTree(LayersId aId);
580
581 /**
582 * Lookup the indirect shadow tree for |aId|, call the function object and
583 * return true if found. If not found, return false.
584 */
585 static bool CallWithIndirectShadowTree(
586 LayersId aId, const std::function<void(LayerTreeState&)>& aFunc);
587
588 /**
589 * Given the layers id for a content process, get the APZCTreeManagerParent
590 * for the corresponding *root* layers id. That is, the APZCTreeManagerParent,
591 * if one is found, will always be connected to the parent process rather
592 * than a content process. Note that unless the compositor process is
593 * separated this is expected to return null, because if the compositor is
594 * living in the gecko parent process then there is no APZCTreeManagerParent
595 * for the parent process.
596 */
597 static APZCTreeManagerParent* GetApzcTreeManagerParentForRoot(
598 LayersId aContentLayersId);
599 /**
600 * Same as the GetApzcTreeManagerParentForRoot function, but returns
601 * the GeckoContentController for the parent process.
602 */
603 static GeckoContentController* GetGeckoContentControllerForRoot(
604 LayersId aContentLayersId);
605
606 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
607 /**
608 * Calculates and requests the main thread update plugin positioning, clip,
609 * and visibility via ipc.
610 */
611 bool UpdatePluginWindowState(LayersId aId);
612
613 /**
614 * Plugin visibility helpers for the apz (main thread) and compositor
615 * thread.
616 */
617 void ScheduleShowAllPluginWindows() override;
618 void ScheduleHideAllPluginWindows() override;
619 void ShowAllPluginWindows();
620 void HideAllPluginWindows();
621 #else
622 void ScheduleShowAllPluginWindows() override {}
623 void ScheduleHideAllPluginWindows() override {}
624 #endif
625
626 /**
627 * Main thread response for a plugin visibility request made by the
628 * compositor thread.
629 */
630 mozilla::ipc::IPCResult RecvRemotePluginsReady() override;
631
632 /**
633 * Used by the profiler to denote when a vsync occured
634 */
635 static void PostInsertVsyncProfilerMarker(mozilla::TimeStamp aVsyncTimestamp);
636
637 widget::CompositorWidget* GetWidget() { return mWidget; }
638
639 virtual void ForceComposeToTarget(
640 gfx::DrawTarget* aTarget, const gfx::IntRect* aRect = nullptr) override;
641
642 PAPZCTreeManagerParent* AllocPAPZCTreeManagerParent(
643 const LayersId& aLayersId) override;
644 bool DeallocPAPZCTreeManagerParent(PAPZCTreeManagerParent* aActor) override;
645
646 // Helper method so that we don't have to expose mApzcTreeManager to
647 // ContentCompositorBridgeParent.
648 void AllocateAPZCTreeManagerParent(
649 const MonitorAutoLock& aProofOfLayerTreeStateLock,
650 const LayersId& aLayersId, LayerTreeState& aLayerTreeStateToUpdate);
651
652 PAPZParent* AllocPAPZParent(const LayersId& aLayersId) override;
653 bool DeallocPAPZParent(PAPZParent* aActor) override;
654
655 RefPtr<APZSampler> GetAPZSampler();
656 RefPtr<APZUpdater> GetAPZUpdater();
657
658 CompositorOptions GetOptions() const { return mOptions; }
659
660 TimeDuration GetVsyncInterval() const override {
661 // the variable is called "rate" but really it's an interval
662 return mVsyncRate;
663 }
664
665 PWebRenderBridgeParent* AllocPWebRenderBridgeParent(
666 const wr::PipelineId& aPipelineId,
667 const LayoutDeviceIntSize& aSize) override;
668 bool DeallocPWebRenderBridgeParent(PWebRenderBridgeParent* aActor) override;
669 RefPtr<WebRenderBridgeParent> GetWebRenderBridgeParent() const;
670 Maybe<TimeStamp> GetTestingTimeStamp() const;
671
672 webgpu::PWebGPUParent* AllocPWebGPUParent() override;
673 bool DeallocPWebGPUParent(webgpu::PWebGPUParent* aActor) override;
674
675 static CompositorBridgeParent* GetCompositorBridgeParentFromLayersId(
676 const LayersId& aLayersId);
677 static RefPtr<CompositorBridgeParent> GetCompositorBridgeParentFromWindowId(
678 const wr::WindowId& aWindowId);
679
680 /**
681 * This returns a reference to the IAPZCTreeManager "controller subinterface"
682 * to which pan/zoom-related events can be sent. The controller subinterface
683 * doesn't expose any sampler-thread APZCTreeManager methods.
684 */
685 static already_AddRefed<IAPZCTreeManager> GetAPZCTreeManager(
686 LayersId aLayersId);
687
688 WebRenderBridgeParent* GetWrBridge() { return mWrBridge; }
689 webgpu::WebGPUParent* GetWebGPUBridge() { return mWebGPUBridge; }
690
691 already_AddRefed<PWebGLParent> AllocPWebGLParent() override {
692 MOZ_ASSERT_UNREACHABLE(
693 "This message is CrossProcessCompositorBridgeParent only");
694 return nullptr;
695 }
696
697 private:
698 void Initialize();
699
700 /**
701 * Called during destruction in order to release resources as early as
702 * possible.
703 */
704 void StopAndClearResources();
705
706 /**
707 * Release compositor-thread resources referred to by |aID|.
708 *
709 * Must run on the content main thread.
710 */
711 static void DeallocateLayerTreeId(LayersId aId);
712
713 /**
714 * Notify the compositor the quality settings have been updated.
715 */
716 static void UpdateQualitySettings();
717
718 /**
719 * Notify the compositor the debug flags have been updated.
720 */
721 static void UpdateDebugFlags();
722
723 /**
724 * Notify the compositor the debug flags have been updated.
725 */
726 static void UpdateWebRenderMultithreading();
727
728 /**
729 * Notify the compositor webrender batching parameters have been updated.
730 */
731 static void UpdateWebRenderBatchingParameters();
732
733 /**
734 * Wrap the data structure to be sent over IPC.
735 */
736 Maybe<CollectedFramesParams> WrapCollectedFrames(CollectedFrames&& aFrames);
737
738 protected:
739 // Protected destructor, to discourage deletion outside of Release():
740 virtual ~CompositorBridgeParent();
741
742 void DeferredDestroy();
743
744 PLayerTransactionParent* AllocPLayerTransactionParent(
745 const nsTArray<LayersBackend>& aBackendHints,
746 const LayersId& aId) override;
747 bool DeallocPLayerTransactionParent(
748 PLayerTransactionParent* aLayers) override;
749
750 void SetEGLSurfaceRect(int x, int y, int width, int height);
751
752 void InitializeLayerManager(const nsTArray<LayersBackend>& aBackendHints);
753
754 public:
755 void PauseComposition();
756 void ResumeComposition();
757 void ResumeCompositionAndResize(int x, int y, int width, int height);
758 void Invalidate();
759 bool IsPaused() { return mPaused; }
760
761 protected:
762 void ForceComposition();
763 void CancelCurrentCompositeTask();
764
765 // CompositorVsyncSchedulerOwner
766 bool IsPendingComposite() override;
767 void FinishPendingComposite() override;
768 void CompositeToTarget(VsyncId aId, gfx::DrawTarget* aTarget,
769 const gfx::IntRect* aRect = nullptr) override;
770
771 bool InitializeAdvancedLayers(const nsTArray<LayersBackend>& aBackendHints,
772 TextureFactoryIdentifier* aOutIdentifier);
773 RefPtr<Compositor> NewCompositor(
774 const nsTArray<LayersBackend>& aBackendHints);
775
776 /**
777 * Add a compositor to the global compositor map.
778 */
779 static void AddCompositor(CompositorBridgeParent* compositor, uint64_t* id);
780 /**
781 * Remove a compositor from the global compositor map.
782 */
783 static CompositorBridgeParent* RemoveCompositor(uint64_t id);
784
785 /**
786 * Creates the global compositor map.
787 */
788 static void Setup();
789
790 /**
791 * Remaning cleanups after the compositore thread is gone.
792 */
793 static void FinishShutdown();
794
795 /**
796 * Return true if current state allows compositing, that is
797 * finishing a layers transaction.
798 */
799 bool CanComposite();
800
801 void DidComposite(const VsyncId& aId, TimeStamp& aCompositeStart,
802 TimeStamp& aCompositeEnd);
803
804 void NotifyDidComposite(TransactionId aTransactionId, VsyncId aId,
805 TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd);
806
807 // The indirect layer tree lock must be held before calling this function.
808 // Callback should take (LayerTreeState* aState, const LayersId& aLayersId)
809 template <typename Lambda>
810 inline void ForEachIndirectLayerTree(const Lambda& aCallback);
811
812 // The indirect layer tree lock must be held before calling this function.
813 // Callback should take (LayerTreeState* aState, const LayersId& aLayersId)
814 template <typename Lambda>
815 static inline void ForEachWebRenderBridgeParent(const Lambda& aCallback);
816
817 RefPtr<HostLayerManager> mLayerManager;
818 RefPtr<Compositor> mCompositor;
819 RefPtr<AsyncCompositionManager> mCompositionManager;
820 RefPtr<AsyncImagePipelineManager> mAsyncImageManager;
821 RefPtr<WebRenderBridgeParent> mWrBridge;
822 RefPtr<webgpu::WebGPUParent> mWebGPUBridge;
823 widget::CompositorWidget* mWidget;
824 Maybe<TimeStamp> mTestTime;
825 CSSToLayoutDeviceScale mScale;
826 TimeDuration mVsyncRate;
827
828 TransactionId mPendingTransaction;
829 TimeStamp mRefreshStartTime;
830 TimeStamp mTxnStartTime;
831 TimeStamp mFwdTime;
832
833 bool mPaused;
834 bool mHaveCompositionRecorder;
835 bool mIsForcedFirstPaint;
836
837 bool mUseExternalSurfaceSize;
838 gfx::IntSize mEGLSurfaceSize;
839
840 CompositorOptions mOptions;
841
842 mozilla::Monitor mPauseCompositionMonitor;
843 mozilla::Monitor mResumeCompositionMonitor;
844
845 uint64_t mCompositorBridgeID;
846 LayersId mRootLayerTreeID;
847
848 bool mOverrideComposeReadiness;
849 RefPtr<CancelableRunnable> mForceCompositionTask;
850
851 RefPtr<APZCTreeManager> mApzcTreeManager;
852 RefPtr<APZSampler> mApzSampler;
853 RefPtr<APZUpdater> mApzUpdater;
854
855 RefPtr<CompositorVsyncScheduler> mCompositorScheduler;
856 // This makes sure the compositorParent is not destroyed before receiving
857 // confirmation that the channel is closed.
858 // mSelfRef is cleared in DeferredDestroy which is scheduled by ActorDestroy.
859 RefPtr<CompositorBridgeParent> mSelfRef;
860 RefPtr<CompositorAnimationStorage> mAnimationStorage;
861
862 TimeDuration mPaintTime;
863
864 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
865 // cached plugin data used to reduce the number of updates we request.
866 LayersId mLastPluginUpdateLayerTreeId;
867 nsIntPoint mPluginsLayerOffset;
868 nsIntRegion mPluginsLayerVisibleRegion;
869 nsTArray<PluginWindowData> mCachedPluginData;
870 // Time until which we will block composition to wait for plugin updates.
871 TimeStamp mWaitForPluginsUntil;
872 // Indicates that we have actually blocked a composition waiting for plugins.
873 bool mHaveBlockedForPlugins = false;
874 // indicates if plugin window visibility and metric updates are currently
875 // being defered due to a scroll operation.
876 bool mDeferPluginWindows;
877 // indicates if the plugin windows were hidden, and need to be made
878 // visible again even if their geometry has not changed.
879 bool mPluginWindowsHidden;
880 #endif
881
882 DISALLOW_EVIL_CONSTRUCTORS(CompositorBridgeParent);
883 };
884
885 int32_t RecordContentFrameTime(
886 const VsyncId& aTxnId, const TimeStamp& aVsyncStart,
887 const TimeStamp& aTxnStart, const VsyncId& aCompositeId,
888 const TimeStamp& aCompositeEnd, const TimeDuration& aFullPaintTime,
889 const TimeDuration& aVsyncRate, bool aContainsSVGGroup,
890 bool aRecordUploadStats, wr::RendererStats* aStats = nullptr);
891
892 } // namespace layers
893 } // namespace mozilla
894
895 #endif // mozilla_layers_CompositorBridgeParent_h
896