зеркало из https://github.com/mozilla/gecko-dev.git
424 строки
15 KiB
C++
424 строки
15 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* 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_CompositorBridgeChild_h
|
|
#define mozilla_layers_CompositorBridgeChild_h
|
|
|
|
#include "base/basictypes.h" // for DISALLOW_EVIL_CONSTRUCTORS
|
|
#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
|
|
#include "mozilla/Attributes.h" // for override
|
|
#include "mozilla/Monitor.h"
|
|
#include "mozilla/ipc/ProtocolUtils.h"
|
|
#include "mozilla/layers/PCompositorBridgeChild.h"
|
|
#include "mozilla/layers/TextureForwarder.h" // for TextureForwarder
|
|
#include "mozilla/layers/PaintThread.h" // for PaintThread
|
|
#include "mozilla/webrender/WebRenderTypes.h"
|
|
#include "nsClassHashtable.h" // for nsClassHashtable
|
|
#include "nsCOMPtr.h" // for nsCOMPtr
|
|
#include "nsHashKeys.h" // for nsUint64HashKey
|
|
#include "nsISupportsImpl.h" // for NS_INLINE_DECL_REFCOUNTING
|
|
#include "nsIWeakReferenceUtils.h"
|
|
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
|
|
|
|
#include <unordered_map>
|
|
|
|
namespace mozilla {
|
|
|
|
namespace dom {
|
|
class BrowserChild;
|
|
} // namespace dom
|
|
|
|
namespace webgpu {
|
|
class PWebGPUChild;
|
|
class WebGPUChild;
|
|
} // namespace webgpu
|
|
|
|
namespace widget {
|
|
class CompositorWidget;
|
|
} // namespace widget
|
|
|
|
namespace layers {
|
|
|
|
using mozilla::dom::BrowserChild;
|
|
|
|
class IAPZCTreeManager;
|
|
class APZCTreeManagerChild;
|
|
class CanvasChild;
|
|
class ClientLayerManager;
|
|
class CompositorBridgeParent;
|
|
class CompositorManagerChild;
|
|
class CompositorOptions;
|
|
class TextureClient;
|
|
class TextureClientPool;
|
|
struct FrameMetrics;
|
|
|
|
class CompositorBridgeChild final : public PCompositorBridgeChild,
|
|
public TextureForwarder {
|
|
typedef nsTArray<AsyncParentMessageData> AsyncParentMessageArray;
|
|
|
|
friend class PCompositorBridgeChild;
|
|
|
|
public:
|
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorBridgeChild, override);
|
|
|
|
explicit CompositorBridgeChild(CompositorManagerChild* aManager);
|
|
|
|
/**
|
|
* Initialize the singleton compositor bridge for a content process.
|
|
*/
|
|
void InitForContent(uint32_t aNamespace);
|
|
|
|
void InitForWidget(uint64_t aProcessToken, LayerManager* aLayerManager,
|
|
uint32_t aNamespace);
|
|
|
|
void Destroy();
|
|
|
|
/**
|
|
* Lookup the FrameMetrics shared by the compositor process with the
|
|
* associated ScrollableLayerGuid::ViewID. The returned FrameMetrics is used
|
|
* in progressive paint calculations.
|
|
*/
|
|
bool LookupCompositorFrameMetrics(const ScrollableLayerGuid::ViewID aId,
|
|
FrameMetrics&);
|
|
|
|
static CompositorBridgeChild* Get();
|
|
|
|
static bool ChildProcessHasCompositorBridge();
|
|
|
|
// Returns whether the compositor is in the GPU process (false if in the UI
|
|
// process). This may only be called on the main thread.
|
|
static bool CompositorIsInGPUProcess();
|
|
|
|
mozilla::ipc::IPCResult RecvDidComposite(const LayersId& aId,
|
|
const TransactionId& aTransactionId,
|
|
const TimeStamp& aCompositeStart,
|
|
const TimeStamp& aCompositeEnd);
|
|
|
|
mozilla::ipc::IPCResult RecvNotifyFrameStats(
|
|
nsTArray<FrameStats>&& aFrameStats);
|
|
|
|
mozilla::ipc::IPCResult RecvInvalidateLayers(const LayersId& aLayersId);
|
|
|
|
mozilla::ipc::IPCResult RecvUpdatePluginConfigurations(
|
|
const LayoutDeviceIntPoint& aContentOffset,
|
|
const LayoutDeviceIntRegion& aVisibleRegion,
|
|
nsTArray<PluginWindowData>&& aPlugins);
|
|
|
|
mozilla::ipc::IPCResult RecvCaptureAllPlugins(const uintptr_t& aParentWidget);
|
|
|
|
mozilla::ipc::IPCResult RecvHideAllPlugins(const uintptr_t& aParentWidget);
|
|
|
|
PTextureChild* AllocPTextureChild(
|
|
const SurfaceDescriptor& aSharedData, const ReadLockDescriptor& aReadLock,
|
|
const LayersBackend& aLayersBackend, const TextureFlags& aFlags,
|
|
const LayersId& aId, const uint64_t& aSerial,
|
|
const wr::MaybeExternalImageId& aExternalImageId);
|
|
|
|
bool DeallocPTextureChild(PTextureChild* actor);
|
|
|
|
mozilla::ipc::IPCResult RecvParentAsyncMessages(
|
|
nsTArray<AsyncParentMessageData>&& aMessages);
|
|
PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
|
|
const ReadLockDescriptor& aReadLock,
|
|
LayersBackend aLayersBackend,
|
|
TextureFlags aFlags, uint64_t aSerial,
|
|
wr::MaybeExternalImageId& aExternalImageId,
|
|
nsIEventTarget* aTarget) override;
|
|
|
|
already_AddRefed<CanvasChild> GetCanvasChild() final;
|
|
|
|
void EndCanvasTransaction();
|
|
|
|
RefPtr<webgpu::WebGPUChild> GetWebGPUChild();
|
|
|
|
/**
|
|
* Request that the parent tell us when graphics are ready on GPU.
|
|
* When we get that message, we bounce it to the BrowserParent via
|
|
* the BrowserChild
|
|
* @param browserChild The object to bounce the note to. Non-NULL.
|
|
*/
|
|
void RequestNotifyAfterRemotePaint(BrowserChild* aBrowserChild);
|
|
|
|
void CancelNotifyAfterRemotePaint(BrowserChild* aBrowserChild);
|
|
|
|
// Beware that these methods don't override their super-class equivalent
|
|
// (which are not virtual), they just overload them. All of these Send*
|
|
// methods just add a sanity check (that it is not too late send a message)
|
|
// and forward the call to the super-class's equivalent method. This means
|
|
// that it is correct to call directly the super-class methods, but you won't
|
|
// get the extra safety provided here.
|
|
bool SendWillClose();
|
|
bool SendPause();
|
|
bool SendResume();
|
|
bool SendResumeAsync();
|
|
bool SendNotifyChildCreated(const LayersId& id, CompositorOptions* aOptions);
|
|
bool SendAdoptChild(const LayersId& id);
|
|
bool SendMakeSnapshot(const SurfaceDescriptor& inSnapshot,
|
|
const gfx::IntRect& dirtyRect);
|
|
bool SendFlushRendering();
|
|
bool SendGetTileSize(int32_t* tileWidth, int32_t* tileHeight);
|
|
bool SendStartFrameTimeRecording(const int32_t& bufferSize,
|
|
uint32_t* startIndex);
|
|
bool SendStopFrameTimeRecording(const uint32_t& startIndex,
|
|
nsTArray<float>* intervals);
|
|
bool SendNotifyRegionInvalidated(const nsIntRegion& region);
|
|
bool SendRequestNotifyAfterRemotePaint();
|
|
bool SendAllPluginsCaptured();
|
|
bool IsSameProcess() const override;
|
|
|
|
bool IPCOpen() const override { return mCanSend; }
|
|
|
|
static void ShutDown();
|
|
|
|
void UpdateFwdTransactionId() { ++mFwdTransactionId; }
|
|
uint64_t GetFwdTransactionId() { return mFwdTransactionId; }
|
|
|
|
/**
|
|
* Hold TextureClient ref until end of usage on host side if
|
|
* TextureFlags::RECYCLE is set. Host side's usage is checked via
|
|
* CompositableRef.
|
|
*/
|
|
void HoldUntilCompositableRefReleasedIfNecessary(TextureClient* aClient);
|
|
|
|
/**
|
|
* Notify id of Texture When host side end its use. Transaction id is used to
|
|
* make sure if there is no newer usage.
|
|
*/
|
|
void NotifyNotUsed(uint64_t aTextureId, uint64_t aFwdTransactionId);
|
|
|
|
void CancelWaitForNotifyNotUsed(uint64_t aTextureId) override;
|
|
|
|
TextureClientPool* GetTexturePool(KnowsCompositor* aAllocator,
|
|
gfx::SurfaceFormat aFormat,
|
|
TextureFlags aFlags);
|
|
void ClearTexturePool();
|
|
|
|
FixedSizeSmallShmemSectionAllocator* GetTileLockAllocator() override;
|
|
|
|
void HandleMemoryPressure();
|
|
|
|
MessageLoop* GetMessageLoop() const override { return mMessageLoop; }
|
|
|
|
base::ProcessId GetParentPid() const override { return OtherPid(); }
|
|
|
|
bool AllocUnsafeShmem(size_t aSize,
|
|
mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
|
|
mozilla::ipc::Shmem* aShmem) override;
|
|
bool AllocShmem(size_t aSize,
|
|
mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
|
|
mozilla::ipc::Shmem* aShmem) override;
|
|
bool DeallocShmem(mozilla::ipc::Shmem& aShmem) override;
|
|
|
|
PCompositorWidgetChild* AllocPCompositorWidgetChild(
|
|
const CompositorWidgetInitData& aInitData);
|
|
bool DeallocPCompositorWidgetChild(PCompositorWidgetChild* aActor);
|
|
|
|
PAPZCTreeManagerChild* AllocPAPZCTreeManagerChild(const LayersId& aLayersId);
|
|
bool DeallocPAPZCTreeManagerChild(PAPZCTreeManagerChild* aActor);
|
|
|
|
PAPZChild* AllocPAPZChild(const LayersId& aLayersId);
|
|
bool DeallocPAPZChild(PAPZChild* aActor);
|
|
|
|
void WillEndTransaction();
|
|
|
|
PWebRenderBridgeChild* AllocPWebRenderBridgeChild(
|
|
const wr::PipelineId& aPipelineId, const LayoutDeviceIntSize&);
|
|
bool DeallocPWebRenderBridgeChild(PWebRenderBridgeChild* aActor);
|
|
|
|
webgpu::PWebGPUChild* AllocPWebGPUChild();
|
|
bool DeallocPWebGPUChild(webgpu::PWebGPUChild* aActor);
|
|
|
|
wr::MaybeExternalImageId GetNextExternalImageId() override;
|
|
|
|
wr::PipelineId GetNextPipelineId();
|
|
|
|
// Must only be called from the main thread. Ensures that any paints from
|
|
// previous frames have been flushed. The main thread blocks until the
|
|
// operation completes.
|
|
void FlushAsyncPaints();
|
|
|
|
// Must only be called from the main thread. Notifies the CompositorBridge
|
|
// that the paint thread is going to begin painting asynchronously.
|
|
void NotifyBeginAsyncPaint(PaintTask* aTask);
|
|
|
|
// Must only be called from the paint thread. Notifies the CompositorBridge
|
|
// that the paint thread has finished an asynchronous paint request.
|
|
bool NotifyFinishedAsyncWorkerPaint(PaintTask* aTask);
|
|
|
|
// Must only be called from the main thread. Notifies the CompositorBridge
|
|
// that all work has been submitted to the paint thread or paint worker
|
|
// threads, and returns whether all paints are completed. If this returns
|
|
// true, then an AsyncEndLayerTransaction must be queued, otherwise once
|
|
// NotifyFinishedAsyncWorkerPaint returns true, an AsyncEndLayerTransaction
|
|
// must be executed.
|
|
bool NotifyBeginAsyncEndLayerTransaction(SyncObjectClient* aSyncObject);
|
|
|
|
// Must only be called from the paint thread. Notifies the CompositorBridge
|
|
// that the paint thread has finished all async paints and and may do the
|
|
// requested texture sync and resume sending messages.
|
|
void NotifyFinishedAsyncEndLayerTransaction();
|
|
|
|
// Must only be called from the main thread. Notifies the CompoistorBridge
|
|
// that a transaction is about to be sent, and if the paint thread is
|
|
// currently painting, to begin delaying IPC messages.
|
|
void PostponeMessagesIfAsyncPainting();
|
|
|
|
private:
|
|
// Private destructor, to discourage deletion outside of Release():
|
|
virtual ~CompositorBridgeChild();
|
|
|
|
// Must only be called from the paint thread. If the main thread is delaying
|
|
// IPC messages, this forwards all such delayed IPC messages to the I/O thread
|
|
// and resumes IPC.
|
|
void ResumeIPCAfterAsyncPaint();
|
|
|
|
void PrepareFinalDestroy();
|
|
void AfterDestroy();
|
|
|
|
PLayerTransactionChild* AllocPLayerTransactionChild(
|
|
const nsTArray<LayersBackend>& aBackendHints, const LayersId& aId);
|
|
|
|
bool DeallocPLayerTransactionChild(PLayerTransactionChild* aChild);
|
|
|
|
void ActorDestroy(ActorDestroyReason aWhy) override;
|
|
|
|
mozilla::ipc::IPCResult RecvSharedCompositorFrameMetrics(
|
|
const mozilla::ipc::SharedMemoryBasic::Handle& metrics,
|
|
const CrossProcessMutexHandle& handle, const LayersId& aLayersId,
|
|
const uint32_t& aAPZCId);
|
|
|
|
mozilla::ipc::IPCResult RecvReleaseSharedCompositorFrameMetrics(
|
|
const ViewID& aId, const uint32_t& aAPZCId);
|
|
|
|
mozilla::ipc::IPCResult RecvRemotePaintIsReady();
|
|
|
|
mozilla::ipc::IPCResult RecvObserveLayersUpdate(
|
|
const LayersId& aLayersId, const LayersObserverEpoch& aEpoch,
|
|
const bool& aActive);
|
|
|
|
mozilla::ipc::IPCResult RecvCompositorOptionsChanged(
|
|
const LayersId& aLayersId, const CompositorOptions& aNewOptions);
|
|
|
|
uint64_t GetNextResourceId();
|
|
|
|
void ClearSharedFrameMetricsData(LayersId aLayersId);
|
|
|
|
// Class used to store the shared FrameMetrics, mutex, and APZCId in a hash
|
|
// table
|
|
class SharedFrameMetricsData final {
|
|
public:
|
|
SharedFrameMetricsData(
|
|
const mozilla::ipc::SharedMemoryBasic::Handle& metrics,
|
|
const CrossProcessMutexHandle& handle, const LayersId& aLayersId,
|
|
const uint32_t& aAPZCId);
|
|
|
|
~SharedFrameMetricsData();
|
|
|
|
void CopyFrameMetrics(FrameMetrics* aFrame);
|
|
ScrollableLayerGuid::ViewID GetViewID();
|
|
LayersId GetLayersId() const;
|
|
uint32_t GetAPZCId();
|
|
|
|
private:
|
|
// Pointer to the class that allows access to the shared memory that
|
|
// contains the shared FrameMetrics
|
|
RefPtr<mozilla::ipc::SharedMemoryBasic> mBuffer;
|
|
CrossProcessMutex* mMutex;
|
|
LayersId mLayersId;
|
|
// Unique ID of the APZC that is sharing the FrameMetrics
|
|
uint32_t mAPZCId;
|
|
};
|
|
|
|
RefPtr<CompositorManagerChild> mCompositorManager;
|
|
|
|
RefPtr<LayerManager> mLayerManager;
|
|
|
|
uint32_t mIdNamespace;
|
|
uint32_t mResourceId;
|
|
|
|
// When not multi-process, hold a reference to the CompositorBridgeParent to
|
|
// keep it alive. This reference should be null in multi-process.
|
|
RefPtr<CompositorBridgeParent> mCompositorBridgeParent;
|
|
|
|
// The ViewID of the FrameMetrics is used as the key for this hash table.
|
|
// While this should be safe to use since the ViewID is unique
|
|
nsClassHashtable<nsUint64HashKey, SharedFrameMetricsData> mFrameMetricsTable;
|
|
|
|
// Weakly hold the BrowserChild that made a request to be alerted when
|
|
// the transaction has been received.
|
|
nsWeakPtr mWeakBrowserChild; // type is BrowserChild
|
|
|
|
DISALLOW_EVIL_CONSTRUCTORS(CompositorBridgeChild);
|
|
|
|
// True until the beginning of the two-step shutdown sequence of this actor.
|
|
bool mCanSend;
|
|
|
|
// False until the actor is destroyed.
|
|
bool mActorDestroyed;
|
|
|
|
/**
|
|
* Transaction id of ShadowLayerForwarder.
|
|
* It is incrementaed by UpdateFwdTransactionId() in each BeginTransaction()
|
|
* call.
|
|
*/
|
|
uint64_t mFwdTransactionId;
|
|
|
|
/**
|
|
* Hold TextureClients refs until end of their usages on host side.
|
|
* It defer calling of TextureClient recycle callback.
|
|
*/
|
|
std::unordered_map<uint64_t, RefPtr<TextureClient>>
|
|
mTexturesWaitingNotifyNotUsed;
|
|
|
|
MessageLoop* mMessageLoop;
|
|
|
|
AutoTArray<RefPtr<TextureClientPool>, 2> mTexturePools;
|
|
|
|
uint64_t mProcessToken;
|
|
|
|
FixedSizeSmallShmemSectionAllocator* mSectionAllocator;
|
|
|
|
// TextureClients that must be kept alive during async painting. This
|
|
// is only accessed on the main thread.
|
|
nsTArray<RefPtr<TextureClient>> mTextureClientsForAsyncPaint;
|
|
|
|
// Off-Main-Thread Painting state. This covers access to the OMTP-related
|
|
// state below.
|
|
Monitor mPaintLock;
|
|
|
|
// Contains the number of asynchronous paints that were queued since the
|
|
// beginning of the last async transaction, and the time stamp of when
|
|
// that was
|
|
size_t mTotalAsyncPaints;
|
|
TimeStamp mAsyncTransactionBegin;
|
|
|
|
// Contains the number of outstanding asynchronous paints tied to a
|
|
// PLayerTransaction on this bridge. This is R/W on both the main and paint
|
|
// threads, and must be accessed within the paint lock.
|
|
size_t mOutstandingAsyncPaints;
|
|
|
|
// Whether we are waiting for an async paint end transaction
|
|
bool mOutstandingAsyncEndTransaction;
|
|
RefPtr<SyncObjectClient> mOutstandingAsyncSyncObject;
|
|
|
|
// True if this CompositorBridge is currently delaying its messages until the
|
|
// paint thread completes. This is R/W on both the main and paint threads, and
|
|
// must be accessed within the paint lock.
|
|
bool mIsDelayingForAsyncPaints;
|
|
|
|
uintptr_t mSlowFlushCount;
|
|
uintptr_t mTotalFlushCount;
|
|
|
|
RefPtr<CanvasChild> mCanvasChild;
|
|
|
|
RefPtr<webgpu::WebGPUChild> mWebGPUChild;
|
|
};
|
|
|
|
} // namespace layers
|
|
} // namespace mozilla
|
|
|
|
#endif // mozilla_layers_CompositorBrigedChild_h
|