/* 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_CompositorBridgeParent_h
#define mozilla_layers_CompositorBridgeParent_h
#include <stdint.h>
// for uint64_t
#include <unordered_map>
#include "mozilla/Maybe.h"
#include "mozilla/Monitor.h" // for Monitor
#include "mozilla/RefPtr.h" // for RefPtr
#include "mozilla/StaticMonitor.h" // for StaticMonitor
#include "mozilla/TimeStamp.h" // for TimeStamp
#include "mozilla/gfx/Point.h" // for IntSize
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/layers/CompositorController.h"
#include "mozilla/layers/CompositorVsyncSchedulerOwner.h"
#include "mozilla/layers/FocusTarget.h"
#include "mozilla/layers/ISurfaceAllocator.h" // for IShmemAllocator
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/layers/PCompositorBridgeParent.h"
#include "mozilla/layers/PWebRenderBridgeParent.h"
#include "mozilla/layers/APZInputBridgeParent.h"
#include "mozilla/webrender/WebRenderTypes.h"
namespace mozilla {
namespace gfx {
class GPUProcessManager;
class GPUParent;
}
// namespace gfx
namespace ipc {
class Shmem;
}
// namespace ipc
namespace widget {
class CompositorWidget;
}
namespace wr {
class WebRenderAPI;
class WebRenderPipelineInfo;
struct Epoch;
struct MemoryReport;
struct PipelineId;
struct RendererStats;
}
// namespace wr
namespace layers {
class APZCTreeManager;
class APZCTreeManagerParent;
class APZSampler;
class APZTestData;
class APZUpdater;
class AsyncImagePipelineManager;
class CompositorAnimationStorage;
class CompositorBridgeParent;
class CompositorManagerParent;
class CompositorVsyncScheduler;
class FrameUniformityData;
class GeckoContentController;
class IAPZCTreeManager;
class OMTASampler;
class ContentCompositorBridgeParent;
class CompositorThreadHolder;
class InProcessCompositorSession;
class UiCompositorControllerParent;
class WebRenderBridgeParent;
class WebRenderScrollDataWrapper;
struct CollectedFrames;
struct ScopedLayerTreeRegistration {
// For WebRender
ScopedLayerTreeRegistration(LayersId aLayersId,
GeckoContentController* aController);
~ScopedLayerTreeRegistration();
private:
LayersId mLayersId;
};
class CompositorBridgeParentBase : public PCompositorBridgeParent,
public CompositorController,
public HostIPCAllocator,
public mozilla::ipc::IShmemAllocator {
friend class PCompositorBridgeParent;
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorBridgeParentBase, final);
explicit CompositorBridgeParentBase(CompositorManagerParent* aManager,
uint32_t aNamespace);
virtual
bool SetTestSampleTime(
const LayersId& aId,
const TimeStamp& aTime) {
return true;
}
virtual
void LeaveTestMode(
const LayersId& aId) {}
enum class TransformsToSkip : uint8_t { NoneOfThem =
0, APZ =
1 };
virtual
void SetTestAsyncScrollOffset(
const LayersId& aLayersId,
const ScrollableLayerGuid::ViewID& aScrollId,
const CSSPoint& aPoint) =
0;
virtual
void SetTestAsyncZoom(
const LayersId& aLayersId,
const ScrollableLayerGuid::ViewID& aScrollId,
const LayerToParentLayerScale& aZoom) =
0;
virtual
void FlushApzRepaints(
const LayersId& aLayersId) =
0;
virtual
void GetAPZTestData(
const LayersId& aLayersId,
APZTestData* aOutData) {}
virtual
void GetFrameUniformity(
const LayersId& aLayersId,
FrameUniformityData* data) =
0;
virtual
void SetConfirmedTargetAPZC(
const LayersId& aLayersId,
const uint64_t& aInputBlockId,
nsTArray<ScrollableLayerGuid>&& aTargets) =
0;
virtual
void EndWheelTransaction(
const LayersId& aLayersId,
PWebRenderBridgeParent::EndWheelTransactionResolver&& aResolve) =
0;
IShmemAllocator* AsShmemAllocator() override {
return this; }
CompositorBridgeParentBase* AsCompositorBridgeParentBase() override {
return this;
}
mozilla::ipc::IPCResult RecvSyncWithCompositor() {
return IPC_OK(); }
mozilla::ipc::IPCResult Recv__delete__() override {
return IPC_OK(); }
virtual
void ObserveLayersUpdate(LayersId aLayersId,
bool aActive) =
0;
// HostIPCAllocator
base::ProcessId GetChildProcessId() override;
dom::ContentParentId GetContentId() override;
void NotifyNotUsed(PTextureParent* aTexture,
uint64_t aTransactionId) override;
void SendAsyncMessage(Span<
const AsyncParentMessageData>) override;
// IShmemAllocator
bool AllocShmem(size_t aSize, mozilla::ipc::Shmem* aShmem) override;
bool AllocUnsafeShmem(size_t aSize, mozilla::ipc::Shmem* aShmem) override;
bool DeallocShmem(mozilla::ipc::Shmem& aShmem) override;
virtual
bool IsRemote()
const {
return false; }
virtual
void NotifyMemoryPressure() {}
virtual
void AccumulateMemoryReport(wr::MemoryReport*) {}
// Ensures the WebRenderBridgeParent has completed initialization (either
// successfully or with failure) by the time this returns. Must be called
// from the Compositor thread.
virtual
void EnsureWebRenderBridgeParentInitialized() =
0;
bool OwnsExternalImageId(
const wr::ExternalImageId& aId)
const;
CompositorManagerParent* GetCompositorManager()
const {
return mCompositorManager;
}
uint32_t GetNamespace()
const {
return mNamespace; }
void SetNamespace(uint32_t aNamespace) { mNamespace = aNamespace; }
protected:
virtual ~CompositorBridgeParentBase();
virtual already_AddRefed<PAPZParent> AllocPAPZParent(
const LayersId& layersId) =
0;
virtual already_AddRefed<PAPZCTreeManagerParent> AllocPAPZCTreeManagerParent(
const LayersId& layersId) =
0;
virtual already_AddRefed<PTextureParent> AllocPTextureParent(
const SurfaceDescriptor& aSharedData, ReadLockDescriptor& aReadLock,
const LayersBackend& aBackend,
const TextureFlags& aTextureFlags,
const uint64_t& aSerial,
const MaybeExternalImageId& aExternalImageId) =
0;
virtual already_AddRefed<PWebRenderBridgeParent> AllocPWebRenderBridgeParent(
const PipelineId& pipelineId,
const LayoutDeviceIntSize& aSize,
const WindowKind& aWindowKind) =
0;
virtual already_AddRefed<PCompositorWidgetParent>
AllocPCompositorWidgetParent(
const CompositorWidgetInitData& aInitData) =
0;
virtual mozilla::ipc::IPCResult RecvAdoptChild(
const LayersId& id) =
0;
virtual mozilla::ipc::IPCResult RecvFlushRenderingAsync(
const wr::RenderReasons& aReasons) =
0;
virtual mozilla::ipc::IPCResult RecvForcePresent(
const wr::RenderReasons& aReasons) =
0;
virtual mozilla::ipc::IPCResult RecvBeginRecording(
const TimeStamp& aRecordingStart, BeginRecordingResolver&& aResolve) =
0;
virtual mozilla::ipc::IPCResult RecvEndRecording(
EndRecordingResolver&& aResolve) =
0;
virtual mozilla::ipc::IPCResult RecvInitialize(
const LayersId& rootLayerTreeId) =
0;
virtual mozilla::ipc::IPCResult RecvWillClose() =
0;
virtual mozilla::ipc::IPCResult RecvPause() =
0;
virtual mozilla::ipc::IPCResult RecvRequestFxrOutput() =
0;
virtual mozilla::ipc::IPCResult RecvResume() =
0;
virtual mozilla::ipc::IPCResult RecvResumeAsync() =
0;
virtual mozilla::ipc::IPCResult RecvNotifyChildCreated(
const LayersId& id, CompositorOptions* compositorOptions) =
0;
virtual mozilla::ipc::IPCResult RecvMapAndNotifyChildCreated(
const LayersId& id,
const ProcessId& owner,
CompositorOptions* compositorOptions) =
0;
virtual mozilla::ipc::IPCResult RecvNotifyChildRecreated(
const LayersId& id, CompositorOptions* compositorOptions) =
0;
virtual mozilla::ipc::IPCResult RecvFlushRendering(
const wr::RenderReasons& aReasons) =
0;
virtual mozilla::ipc::IPCResult RecvNotifyMemoryPressure() =
0;
virtual mozilla::ipc::IPCResult RecvWaitOnTransactionProcessed() =
0;
virtual mozilla::ipc::IPCResult RecvStartFrameTimeRecording(
const int32_t& bufferSize, uint32_t* startIndex) =
0;
virtual mozilla::ipc::IPCResult RecvStopFrameTimeRecording(
const uint32_t& startIndex, nsTArray<
float>* intervals) =
0;
virtual mozilla::ipc::IPCResult RecvCheckContentOnlyTDR(
const uint32_t& sequenceNum,
bool* isContentOnlyTDR) =
0;
virtual mozilla::ipc::IPCResult RecvCheckAndClearWRDidRasterize(
const LayersId& aId,
bool* aDidRasterize) =
0;
virtual mozilla::ipc::IPCResult RecvDynamicToolbarOffsetChanged(
const int32_t& aOffset) =
0;
bool mCanSend;
protected:
RefPtr<CompositorManagerParent> mCompositorManager;
uint32_t mNamespace;
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(
CompositorBridgeParentBase::TransformsToSkip)
class CompositorBridgeParent final : public CompositorBridgeParentBase {
friend class CompositorThreadHolder;
friend class InProcessCompositorSession;
friend class gfx::GPUProcessManager;
friend class gfx::GPUParent;
friend class PCompositorBridgeParent;
public:
explicit CompositorBridgeParent(
CompositorManagerParent* aManager, uint32_t aNamespace,
CSSToLayoutDeviceScale aScale,
const TimeDuration& aVsyncRate,
const CompositorOptions& aOptions,
bool aUseExternalSurfaceSize,
const gfx::IntSize& aSurfaceSize, uint64_t aInnerWindowId);
void InitSameProcess(widget::CompositorWidget* aWidget,
const LayersId& aLayerTreeId);
#ifdef XP_MACOSX
// macOS platform-specific initdata uses move semantics, which
// changes the method signature. Other platforms don't need to
// override the existing method.
mozilla::ipc::IPCResult RecvPCompositorWidgetConstructor(
PCompositorWidgetParent* actor,
CompositorWidgetInitData&& aInitData) override;
#endif
mozilla::ipc::IPCResult RecvInitialize(
const LayersId& aRootLayerTreeId) override;
mozilla::ipc::IPCResult RecvWillClose() override;
mozilla::ipc::IPCResult RecvPause() override;
mozilla::ipc::IPCResult RecvRequestFxrOutput() override;
mozilla::ipc::IPCResult RecvResume() override;
mozilla::ipc::IPCResult RecvResumeAsync() override;
mozilla::ipc::IPCResult RecvNotifyChildCreated(
const LayersId& child, CompositorOptions* aOptions) override;
mozilla::ipc::IPCResult RecvMapAndNotifyChildCreated(
const LayersId& child,
const base::ProcessId& pid,
CompositorOptions* aOptions) override;
mozilla::ipc::IPCResult RecvNotifyChildRecreated(
const LayersId& child, CompositorOptions* aOptions) override;
mozilla::ipc::IPCResult RecvAdoptChild(
const LayersId& child) override;
mozilla::ipc::IPCResult RecvFlushRendering(
const wr::RenderReasons& aReasons) override;
mozilla::ipc::IPCResult RecvFlushRenderingAsync(
const wr::RenderReasons& aReasons) override;
mozilla::ipc::IPCResult RecvWaitOnTransactionProcessed() override;
mozilla::ipc::IPCResult RecvForcePresent(
const wr::RenderReasons& aReasons) override;
mozilla::ipc::IPCResult RecvStartFrameTimeRecording(
const int32_t& aBufferSize, uint32_t* aOutStartIndex) override;
mozilla::ipc::IPCResult RecvStopFrameTimeRecording(
const uint32_t& aStartIndex, nsTArray<
float>* intervals) override;
mozilla::ipc::IPCResult RecvCheckContentOnlyTDR(
const uint32_t& sequenceNum,
bool* isContentOnlyTDR) override {
return IPC_OK();
}
mozilla::ipc::IPCResult RecvCheckAndClearWRDidRasterize(
const LayersId& aId,
bool* aDidRasterize) override;
mozilla::ipc::IPCResult RecvDynamicToolbarOffsetChanged(
const int32_t& aOffset) override;
mozilla::ipc::IPCResult RecvNotifyMemoryPressure() override;
mozilla::ipc::IPCResult RecvBeginRecording(
const TimeStamp& aRecordingStart,
BeginRecordingResolver&& aResolve) override;
mozilla::ipc::IPCResult RecvEndRecording(
EndRecordingResolver&& aResolve) override;
void NotifyMemoryPressure() override;
void AccumulateMemoryReport(wr::MemoryReport*) override;
void ActorDestroy(ActorDestroyReason why) override;
bool SetTestSampleTime(
const LayersId& aId,
const TimeStamp& aTime) override;
void LeaveTestMode(
const LayersId& aId) override;
CompositorAnimationStorage* GetAnimationStorage();
using JankedAnimations =
std::unordered_map<LayersId, nsTArray<uint64_t>, LayersId::HashFn>;
void NotifyJankedAnimations(
const JankedAnimations& aJankedAnimations);
void SetTestAsyncScrollOffset(
const LayersId& aLayersId,
const ScrollableLayerGuid::ViewID& aScrollId,
const CSSPoint& aPoint) override;
void SetTestAsyncZoom(
const LayersId& aLayersId,
const ScrollableLayerGuid::ViewID& aScrollId,
const LayerToParentLayerScale& aZoom) override;
void FlushApzRepaints(
const LayersId& aLayersId) override;
void GetAPZTestData(
const LayersId& aLayersId,
APZTestData* aOutData) override;
void GetFrameUniformity(
const LayersId& aLayersId,
FrameUniformityData* data) override;
void SetConfirmedTargetAPZC(
const LayersId& aLayersId,
const uint64_t& aInputBlockId,
nsTArray<ScrollableLayerGuid>&& aTargets) override;
void SetFixedLayerMargins(ScreenIntCoord aTop, ScreenIntCoord aBottom);
void EndWheelTransaction(
const LayersId& aLayersId,
PWebRenderBridgeParent::EndWheelTransactionResolver&& aResolve) override;
already_AddRefed<PTextureParent> AllocPTextureParent(
const SurfaceDescriptor& aSharedData, ReadLockDescriptor& aReadLock,
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId) override;
bool IsSameProcess()
const override;
void NotifyDidRender(
const VsyncId& aCompositeStartId,
TimeStamp& aCompositeStart, TimeStamp& aRenderStart,
TimeStamp& aCompositeEnd,
wr::RendererStats* aStats = nullptr);
void NotifyPipelineRendered(
const wr::PipelineId& aPipelineId,
const wr::Epoch& aEpoch,
const VsyncId& aCompositeStartId,
TimeStamp& aCompositeStart,
TimeStamp& aRenderStart, TimeStamp& aCompositeEnd,
wr::RendererStats* aStats = nullptr);
void ScheduleFrameAfterSceneBuild(
RefPtr<
const wr::WebRenderPipelineInfo> aInfo);
RefPtr<AsyncImagePipelineManager> GetAsyncImagePipelineManager()
const;
already_AddRefed<PCompositorWidgetParent> AllocPCompositorWidgetParent(
const CompositorWidgetInitData& aInitData) override;
void ObserveLayersUpdate(LayersId aLayersId,
bool aActive) override {}
/**
* This forces the is-first-paint flag to true. This is intended to
* be called by the widget code when it loses its viewport information
* (or for whatever reason wants to refresh the viewport information).
* The information refresh happens because the compositor will call
* SetFirstPaintViewport on the next frame of composition.
*/
void ForceIsFirstPaint();
void NotifyChildCreated(LayersId aChild);
void AsyncRender();
// Can be called from any thread
void ScheduleRenderOnCompositorThread(wr::RenderReasons aReasons) override;
void ScheduleComposition(wr::RenderReasons aReasons);
static void ScheduleForcedComposition(
const LayersId& aLayersId,
wr::RenderReasons aReasons);
static void DisconnectWrBridge(WebRenderBridgeParent* aWrBridge);
static void DisconnectApzcTreeManager(APZCTreeManagerParent* aTreeManager);
/**
* Returns the unique layer tree identifier that corresponds to the root
* tree of this compositor.
*/
LayersId RootLayerTreeId();
/**
* Initialize statics.
*/
static void InitializeStatics();
/**
* Notify the compositor for the given layer tree that vsync has occurred.
*/
static void NotifyVsync(
const VsyncEvent& aVsync,
const LayersId& aLayersId);
/**
* Set aController as the pan/zoom callback for the subtree referred
* to by aLayersId.
*
* Must run on content main thread.
*/
static void SetControllerForLayerTree(LayersId aLayersId,
GeckoContentController* aController);
struct LayerTreeState {
LayerTreeState();
~LayerTreeState();
RefPtr<GeckoContentController> mController;
RefPtr<APZCTreeManagerParent> mApzcTreeManagerParent;
// The mApzInputBridgeParent is only populated for LayerTreeState
// objects corresponding to root LayerIds (one for each top-level
// window).
RefPtr<APZInputBridgeParent> mApzInputBridgeParent;
RefPtr<CompositorBridgeParent> mParent;
RefPtr<WebRenderBridgeParent> mWrBridge;
// The mWebRenderAPI is only populated for LayerTreeState objects
// corresponding to root LayerIds (one for each top-level window).
RefPtr<wr::WebRenderAPI> mWebRenderAPI;
// Pointer to the ContentCompositorBridgeParent. Used by APZCs to share
// their FrameMetrics with the corresponding child process that holds
// the PCompositorBridgeChild
ContentCompositorBridgeParent* mContentCompositorBridgeParent;
CompositorController* GetCompositorController()
const;
RefPtr<UiCompositorControllerParent> mUiControllerParent;
};
/**
* Lookup the indirect shadow tree for |aId| and return it if it
* exists. Otherwise null is returned. This must only be called on
* the compositor thread.
*/
static LayerTreeState* GetLayerTreeState(LayersId aId);
/**
* If a shadow tree exists for the given id |aId|, return true. Otherwise
* return false.
*/
static bool HasLayerTreeState(LayersId aId);
/**
* Lookup the indirect shadow tree for |aId|, call the function object and
* return true if found. If not found, return false.
*/
static bool CallWithLayerTreeState(
LayersId aId,
const std::function<
void(LayerTreeState&)>& aFunc);
// The indirect layer tree map and its lock are private. Code outside of
// CompositorBridgeParent must go through the accessors below, which makes the
// dangerous std::map::operator[] (which silently resurrects an erased entry
// with a null state) unavailable to callers. WithIndirectLayerTreesLock is
// the only way to take the lock; it passes a proof token that the *UnderLock
// accessors require.
template <typename Function>
static auto WithIndirectLayerTreesLock(Function&& aFn) {
StaticMonitorAutoLock lock(sIndirectLayerTreesLock);
return aFn(lock);
}
// Non-inserting lookup; returns nullptr if there is no entry for |aId|.
static LayerTreeState* GetLayerTreeStateUnderLock(
LayersId aId,
const StaticMonitorAutoLock& aProofOfLock);
// Returns the entry for |aId|, inserting a fresh one if absent. This is the
// only way for external callers to add an entry, so insertion is always
// explicit at the call site.
static LayerTreeState& EnsureLayerTreeStateUnderLock(
LayersId aId,
const StaticMonitorAutoLock& aProofOfLock);
// Erases the entry for |aId| if present.
static void EraseLayerTreeStateUnderLock(
LayersId aId,
const StaticMonitorAutoLock& aProofOfLock);
// Iterates every entry. aFn should take (LayersId, LayerTreeState&).
template <typename Function>
static void ForEachLayerTreeStateUnderLock(
const StaticMonitorAutoLock& aProofOfLock, Function&& aFn) {
sIndirectLayerTreesLock.AssertCurrentThreadOwns();
for (
auto& entry : sIndirectLayerTrees) {
aFn(entry.first, entry.second);
}
}
/**
* Given the layers id for a content process, get the APZCTreeManagerParent
* for the corresponding *root* layers id. That is, the APZCTreeManagerParent,
* if one is found, will always be connected to the parent process rather
* than a content process. Note that unless the compositor process is
* separated this is expected to return null, because if the compositor is
* living in the gecko parent process then there is no APZCTreeManagerParent
* for the parent process.
*/
static RefPtr<APZCTreeManagerParent> GetApzcTreeManagerParentForRoot(
LayersId aContentLayersId);
/**
* Same as the GetApzcTreeManagerParentForRoot function, but returns
* the GeckoContentController for the parent process.
*/
static GeckoContentController* GetGeckoContentControllerForRoot(
LayersId aContentLayersId);
/**
* Same as the GetApzcTreeManagerParentForRoot function, but returns
* the APZInputBridge for the parent process.
*/
static RefPtr<APZInputBridgeParent> GetApzInputBridgeParentForRoot(
LayersId aContentLayersId);
/**
* Used by the profiler to denote when a vsync occured
*/
static void PostInsertVsyncProfilerMarker(mozilla::TimeStamp aVsyncTimestamp);
widget::CompositorWidget* GetWidget() {
return mWidget; }
already_AddRefed<PAPZCTreeManagerParent> AllocPAPZCTreeManagerParent(
const LayersId& aLayersId) override;
// Helper method so that we don't have to expose mApzcTreeManager to
// ContentCompositorBridgeParent.
already_AddRefed<APZCTreeManagerParent> AllocateAPZCTreeManagerParent(
const StaticMonitorAutoLock& aProofOfLayerTreeStateLock,
const LayersId& aLayersId, LayerTreeState& aLayerTreeStateToUpdate);
static void SetAPZInputBridgeParent(
const LayersId& aLayersId,
RefPtr<APZInputBridgeParent>&& aInputBridgeParent);
already_AddRefed<PAPZParent> AllocPAPZParent(
const LayersId& aLayersId) override;
RefPtr<APZSampler> GetAPZSampler()
const;
RefPtr<APZUpdater> GetAPZUpdater()
const;
RefPtr<OMTASampler> GetOMTASampler()
const;
uint64_t GetInnerWindowId()
const {
return mInnerWindowId; }
CompositorOptions GetOptions()
const {
return mOptions; }
TimeDuration GetVsyncInterval()
const {
// the variable is called "rate" but really it's an interval
return mVsyncRate;
}
already_AddRefed<PWebRenderBridgeParent> AllocPWebRenderBridgeParent(
const wr::PipelineId& aPipelineId,
const LayoutDeviceIntSize& aSize,
const WindowKind& aWindowKind) override;
void EnsureWebRenderBridgeParentInitialized() override;
RefPtr<WebRenderBridgeParent> GetWebRenderBridgeParent()
const;
Maybe<TimeStamp> GetTestingTimeStamp()
const;
static CompositorBridgeParent* GetCompositorBridgeParentFromLayersId(
const LayersId& aLayersId);
static RefPtr<CompositorBridgeParent> GetCompositorBridgeParentFromWindowId(
const wr::WindowId& aWindowId);
/**
* This returns a reference to the IAPZCTreeManager "controller subinterface"
* to which pan/zoom-related events can be sent. The controller subinterface
* doesn't expose any sampler-thread APZCTreeManager methods.
*/
static already_AddRefed<IAPZCTreeManager> GetAPZCTreeManager(
LayersId aLayersId);
WebRenderBridgeParent* GetWrBridge() {
return mWrBridge; }
void FlushPendingWrTransactionEventsWithWait();
private:
/**
* Lookup the indirect shadow tree for |aId| and return it if it
* exists. Otherwise null is returned.
*/
static LayerTreeState* GetLayerTreeStateInternal(LayersId aId);
void Initialize();
/**
* Called during destruction in order to release resources as early as
* possible.
*/
void StopAndClearResources();
/**
* Release compositor-thread resources referred to by |aID|.
*
* Must run on the content main thread.
*/
static void DeallocateLayerTreeId(LayersId aId);
/**
* Notify the compositor the quality settings have been updated.
*/
static void UpdateQualitySettings();
/**
* Notify the compositor the debug flags have been updated.
*/
static void UpdateDebugFlags();
/**
* Notify the compositor some webrender parameters have been updated.
*/
static void UpdateWebRenderParameters();
/**
* Notify the compositor some webrender parameters have been updated.
*/
static void UpdateWebRenderBoolParameters();
/**
* Notify the compositor webrender profiler UI string has been updated.
*/
static void UpdateWebRenderProfilerUI();
static void ResetStable();
void MaybeDeclareStable();
protected:
// Protected destructor, to discourage deletion outside of Release():
virtual ~CompositorBridgeParent();
void DeferredDestroy();
void SetEGLSurfaceRect(
int x,
int y,
int width,
int height);
public:
void PauseComposition();
bool ResumeComposition();
bool ResumeCompositionAndResize(
int x,
int y,
int width,
int height);
bool IsPaused();
// A std::map, but with operator[] deleted. operator[] silently inserts a
// default (null) entry on a missing key, and using it to read or mutate an
// already-erased layer tree during shutdown resurrects a bogus entry. Callers
// must instead go through the accessors below, which make lookup vs insertion
// explicit: GetLayerTreeStateUnderLock (non-inserting),
// CallWithLayerTreeState (mutate-if-present), EnsureLayerTreeStateUnderLock
// (explicit insert) and EraseLayerTreeStateUnderLock.
struct LayerTreeMap
: public std::map<LayersId, CompositorBridgeParent::LayerTreeState> {
mapped_type&
operator[](
const key_type&) =
delete;
mapped_type&
operator[](key_type&&) =
delete;
};
private:
static StaticMonitor sIndirectLayerTreesLock;
static LayerTreeMap sIndirectLayerTrees
MOZ_GUARDED_BY(sIndirectLayerTreesLock);
protected:
/**
* Remaning cleanups after the compositore thread is gone.
*/
static void FinishShutdown();
// The indirect layer tree lock must be held before calling this function.
// Callback should take (LayerTreeState* aState, const LayersId& aLayersId)
template <typename Lambda>
inline void ForEachIndirectLayerTree(
const Lambda& aCallback);
// The indirect layer tree lock must be held before calling this function.
// Callback should take (LayerTreeState* aState, const LayersId& aLayersId)
template <typename Lambda>
static inline void ForEachWebRenderBridgeParent(
const Lambda& aCallback);
static bool sStable;
static uint32_t sFramesComposited;
RefPtr<AsyncImagePipelineManager> mAsyncImageManager;
// Whether mWrBridge has finished initialization (either successfully or with
// failure).
bool mWrBridgeInitialized =
false;
Monitor mWrApiResultMonitor{
"CompositorBridgeParent::mWrApiMonitor"};
// Holds the result of WebRenderAPI creation. Set from the Renderer thread
// and read by the Compositor thread.
Maybe<mozilla::Result<RefPtr<wr::WebRenderAPI>, nsCString>> mWrApiResult
MOZ_GUARDED_BY(mWrApiResultMonitor);
RefPtr<WebRenderBridgeParent> mWrBridge;
widget::CompositorWidget* mWidget;
Maybe<TimeStamp> mTestTime;
CSSToLayoutDeviceScale mScale;
TimeDuration mVsyncRate;
bool mPaused;
bool mHaveCompositionRecorder;
bool mIsForcedFirstPaint;
bool mUseExternalSurfaceSize;
gfx::IntSize mEGLSurfaceSize;
CompositorOptions mOptions;
LayersId mRootLayerTreeID;
RefPtr<APZCTreeManager> mApzcTreeManager;
RefPtr<APZSampler> mApzSampler;
RefPtr<APZUpdater> mApzUpdater;
RefPtr<OMTASampler> mOMTASampler;
// Store the inner window id of the browser window, to use it in
// profiler markers.
uint64_t mInnerWindowId;
RefPtr<CompositorVsyncScheduler> mCompositorScheduler;
// This makes sure the compositorParent is not destroyed before receiving
// confirmation that the channel is closed.
// mSelfRef is cleared in DeferredDestroy which is scheduled by ActorDestroy.
RefPtr<CompositorBridgeParent> mSelfRef;
RefPtr<CompositorAnimationStorage> mAnimationStorage;
DISALLOW_EVIL_CONSTRUCTORS(CompositorBridgeParent);
};
int32_t RecordContentFrameTime(
const VsyncId& aTxnId,
const TimeStamp& aVsyncStart,
const TimeStamp& aTxnStart,
const VsyncId& aCompositeId,
const TimeStamp& aCompositeEnd,
const TimeDuration& aFullPaintTime,
const TimeDuration& aVsyncRate,
bool aContainsSVGGroup,
bool aRecordUploadStats, wr::RendererStats* aStats = nullptr);
void RecordCompositionPayloadsPresented(
const TimeStamp& aCompositionEndTime,
const nsTArray<CompositionPayload>& aPayloads);
}
// namespace layers
}
// namespace mozilla
#endif // mozilla_layers_CompositorBridgeParent_h