Use async compositable IDs for image composite notifications. (bug 1325784 part 4, r=nical)

This commit is contained in:
David Anderson 2017-01-04 10:19:30 -05:00
parent 2d302f4637
commit 944e8cc055
19 changed files with 104 additions and 102 deletions

View File

@ -360,7 +360,7 @@ ImageContainer::GetCurrentSize()
}
void
ImageContainer::NotifyCompositeInternal(const ImageCompositeNotification& aNotification)
ImageContainer::NotifyComposite(const ImageCompositeNotification& aNotification)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);

View File

@ -562,6 +562,8 @@ public:
return mDroppedImageCount;
}
void NotifyComposite(const ImageCompositeNotification& aNotification);
PImageContainerChild* GetPImageContainerChild();
/**
@ -585,8 +587,6 @@ private:
void EnsureImageClient(bool aCreate);
void NotifyCompositeInternal(const ImageCompositeNotification& aNotification);
// ReentrantMonitor to protect thread safe access to the "current
// image", and any other state which is shared between threads.
ReentrantMonitor mReentrantMonitor;

View File

@ -71,15 +71,16 @@ CompositableChild::ActorDestroy(ActorDestroyReason)
}
/* static */ PCompositableChild*
AsyncCompositableChild::CreateActor()
AsyncCompositableChild::CreateActor(uint64_t aAsyncID)
{
AsyncCompositableChild* child = new AsyncCompositableChild();
AsyncCompositableChild* child = new AsyncCompositableChild(aAsyncID);
child->AddRef();
return child;
}
AsyncCompositableChild::AsyncCompositableChild()
: mLock("AsyncCompositableChild.mLock")
AsyncCompositableChild::AsyncCompositableChild(uint64_t aAsyncID)
: mLock("AsyncCompositableChild.mLock"),
mAsyncID(aAsyncID)
{
}

View File

@ -61,7 +61,7 @@ protected:
class AsyncCompositableChild final : public CompositableChild
{
public:
static PCompositableChild* CreateActor();
static PCompositableChild* CreateActor(uint64_t aAsyncID);
void RevokeCompositableClient() override;
RefPtr<CompositableClient> GetCompositableClient() override;
@ -72,12 +72,17 @@ public:
return this;
}
uint64_t GetAsyncID() const {
return mAsyncID;
}
protected:
AsyncCompositableChild();
explicit AsyncCompositableChild(uint64_t aAsyncID);
~AsyncCompositableChild() override;
private:
Mutex mLock;
uint64_t mAsyncID;
};
} // namespace layers

View File

@ -40,16 +40,10 @@ class Compositor;
class CompositableParent : public ParentActor<PCompositableParent>
{
public:
CompositableParent(CompositableParentManager* aMgr,
const TextureInfo& aTextureInfo,
PImageContainerParent* aImageContainer = nullptr)
CompositableParent(CompositableParentManager* aMgr, const TextureInfo& aTextureInfo)
{
MOZ_COUNT_CTOR(CompositableParent);
mHost = CompositableHost::Create(aTextureInfo);
if (aImageContainer) {
mHost->SetImageContainer(
static_cast<ImageContainerParent*>(aImageContainer));
}
}
~CompositableParent()
@ -69,7 +63,6 @@ public:
CompositableHost::CompositableHost(const TextureInfo& aTextureInfo)
: mTextureInfo(aTextureInfo)
, mAsyncID(0)
, mCompositorID(0)
, mCompositor(nullptr)
, mLayer(nullptr)
@ -87,10 +80,9 @@ CompositableHost::~CompositableHost()
PCompositableParent*
CompositableHost::CreateIPDLActor(CompositableParentManager* aMgr,
const TextureInfo& aTextureInfo,
PImageContainerParent* aImageContainer)
const TextureInfo& aTextureInfo)
{
return new CompositableParent(aMgr, aTextureInfo, aImageContainer);
return new CompositableParent(aMgr, aTextureInfo);
}
bool

View File

@ -40,13 +40,26 @@ namespace layers {
class Layer;
class LayerComposite;
class Compositor;
class ImageContainerParent;
class ThebesBufferData;
class TiledContentHost;
class CompositableParentManager;
class PCompositableParent;
struct EffectChain;
struct AsyncCompositableRef
{
AsyncCompositableRef()
: mProcessId(mozilla::ipc::kInvalidProcessId),
mAsyncId(0)
{}
AsyncCompositableRef(base::ProcessId aProcessId, uint64_t aAsyncId)
: mProcessId(aProcessId), mAsyncId(aAsyncId)
{}
explicit operator bool() const { return !!mAsyncId; }
base::ProcessId mProcessId;
uint64_t mAsyncId;
};
/**
* The compositor-side counterpart to CompositableClient. Responsible for
* updating textures and data about textures from IPC and how textures are
@ -135,8 +148,6 @@ public:
Layer* GetLayer() const { return mLayer; }
void SetLayer(Layer* aLayer) { mLayer = aLayer; }
virtual void SetImageContainer(ImageContainerParent* aImageContainer) {}
virtual TiledContentHost* AsTiledContentHost() { return nullptr; }
typedef uint32_t AttachFlags;
@ -212,8 +223,7 @@ public:
static PCompositableParent*
CreateIPDLActor(CompositableParentManager* mgr,
const TextureInfo& textureInfo,
PImageContainerParent* aImageContainer = nullptr);
const TextureInfo& textureInfo);
static bool DestroyIPDLActor(PCompositableParent* actor);
@ -221,12 +231,11 @@ public:
uint64_t GetCompositorID() const { return mCompositorID; }
uint64_t GetAsyncID() const { return mAsyncID; }
const AsyncCompositableRef& GetAsyncRef() const { return mAsyncRef; }
void SetAsyncRef(const AsyncCompositableRef& aRef) { mAsyncRef = aRef; }
void SetCompositorID(uint64_t aID) { mCompositorID = aID; }
void SetAsyncID(uint64_t aID) { mAsyncID = aID; }
virtual bool Lock() { return false; }
virtual void Unlock() { }
@ -242,7 +251,7 @@ public:
protected:
TextureInfo mTextureInfo;
uint64_t mAsyncID;
AsyncCompositableRef mAsyncRef;
uint64_t mCompositorID;
RefPtr<Compositor> mCompositor;
Layer* mLayer;

View File

@ -29,7 +29,6 @@ class ISurfaceAllocator;
ImageHost::ImageHost(const TextureInfo& aTextureInfo)
: CompositableHost(aTextureInfo)
, mImageContainer(nullptr)
, mLastFrameID(-1)
, mLastProducerID(-1)
, mBias(BIAS_NONE)
@ -38,7 +37,6 @@ ImageHost::ImageHost(const TextureInfo& aTextureInfo)
ImageHost::~ImageHost()
{
SetImageContainer(nullptr);
}
void
@ -349,12 +347,15 @@ ImageHost::Composite(LayerComposite* aLayer,
}
if (mLastFrameID != img->mFrameID || mLastProducerID != img->mProducerID) {
if (mImageContainer) {
if (mAsyncRef) {
ImageCompositeNotificationInfo info;
info.mImageBridgeProcessId = mAsyncRef.mProcessId;
info.mNotification = ImageCompositeNotification(
mAsyncRef.mAsyncId,
img->mTimeStamp, GetCompositor()->GetCompositionTime(),
img->mFrameID, img->mProducerID);
static_cast<LayerManagerComposite*>(aLayer->GetLayerManager())->
AppendImageCompositeNotification(ImageCompositeNotification(
mImageContainer, nullptr,
img->mTimeStamp, GetCompositor()->GetCompositionTime(),
img->mFrameID, img->mProducerID));
AppendImageCompositeNotification(info);
}
mLastFrameID = img->mFrameID;
mLastProducerID = img->mProducerID;
@ -578,17 +579,5 @@ ImageHost::GenEffect(const gfx::SamplingFilter aSamplingFilter)
GetRenderState());
}
void
ImageHost::SetImageContainer(ImageContainerParent* aImageContainer)
{
if (mImageContainer) {
mImageContainer->mImageHosts.RemoveElement(this);
}
mImageContainer = aImageContainer;
if (mImageContainer) {
mImageContainer->mImageHosts.AppendElement(this);
}
}
} // namespace layers
} // namespace mozilla

View File

@ -67,8 +67,6 @@ public:
virtual void SetCompositor(Compositor* aCompositor) override;
virtual void SetImageContainer(ImageContainerParent* aImageContainer) override;
gfx::IntSize GetImageSize() const override;
virtual LayerRenderState GetRenderState() override;
@ -147,8 +145,6 @@ protected:
int ChooseImageIndex() const;
nsTArray<TimedImage> mImages;
// Weak reference, will be null if mImageContainer has been destroyed.
ImageContainerParent* mImageContainer;
int32_t mLastFrameID;
int32_t mLastProducerID;
/**

View File

@ -65,6 +65,11 @@ class PaintCounter;
static const int kVisualWarningDuration = 150; // ms
struct ImageCompositeNotificationInfo {
base::ProcessId mImageBridgeProcessId;
ImageCompositeNotification mNotification;
};
// An implementation of LayerManager that acts as a pair with ClientLayerManager
// and is mirrored across IPDL. This gets managed/updated by LayerTransactionParent.
class HostLayerManager : public LayerManager
@ -128,7 +133,7 @@ public:
// layer or texture updates against the old compositor.
virtual void ChangeCompositor(Compositor* aNewCompositor) = 0;
void ExtractImageCompositeNotifications(nsTArray<ImageCompositeNotification>* aNotifications)
void ExtractImageCompositeNotifications(nsTArray<ImageCompositeNotificationInfo>* aNotifications)
{
aNotifications->AppendElements(Move(mImageCompositeNotifications));
}
@ -165,7 +170,7 @@ public:
protected:
bool mDebugOverlayWantsNextFrame;
nsTArray<ImageCompositeNotification> mImageCompositeNotifications;
nsTArray<ImageCompositeNotificationInfo> mImageCompositeNotifications;
// Testing property. If hardware composer is supported, this will return
// true if the last frame was deemed 'too complicated' to be rendered.
float mWarningLevel;
@ -346,7 +351,8 @@ public:
bool AsyncPanZoomEnabled() const override;
void AppendImageCompositeNotification(const ImageCompositeNotification& aNotification)
public:
void AppendImageCompositeNotification(const ImageCompositeNotificationInfo& aNotification)
{
// Only send composite notifications when we're drawing to the screen,
// because that's what they mean.
@ -357,6 +363,8 @@ public:
mImageCompositeNotifications.AppendElement(aNotification);
}
}
public:
virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() override
{
return mCompositor->GetTextureFactoryIdentifier();

View File

@ -1724,7 +1724,7 @@ CompositorBridgeParent::DidComposite(TimeStamp& aCompositeStart,
mPendingTransaction = 0;
if (mLayerManager) {
nsTArray<ImageCompositeNotification> notifications;
nsTArray<ImageCompositeNotificationInfo> notifications;
mLayerManager->ExtractImageCompositeNotifications(&notifications);
if (!notifications.IsEmpty()) {
Unused << ImageBridgeParent::NotifyImageComposites(notifications);

View File

@ -383,14 +383,11 @@ ImageBridgeChild::Connect(CompositableClient* aCompositable,
static uint64_t sNextID = 1;
uint64_t id = sNextID++;
PImageContainerChild* imageContainerChild = nullptr;
if (aImageContainer)
imageContainerChild = aImageContainer->GetPImageContainerChild();
MOZ_ASSERT(!mImageContainers.Contains(id));
mImageContainers.Put(id, aImageContainer);
PCompositableChild* child =
SendPCompositableConstructor(aCompositable->GetTextureInfo(),
id,
imageContainerChild);
SendPCompositableConstructor(aCompositable->GetTextureInfo(), id);
if (!child) {
return;
}
@ -398,17 +395,20 @@ ImageBridgeChild::Connect(CompositableClient* aCompositable,
}
PCompositableChild*
ImageBridgeChild::AllocPCompositableChild(const TextureInfo& aInfo,
const uint64_t& aID,
PImageContainerChild* aChild)
ImageBridgeChild::AllocPCompositableChild(const TextureInfo& aInfo, const uint64_t& aID)
{
MOZ_ASSERT(CanSend());
return AsyncCompositableChild::CreateActor();
return AsyncCompositableChild::CreateActor(aID);
}
bool
ImageBridgeChild::DeallocPCompositableChild(PCompositableChild* aActor)
{
AsyncCompositableChild* actor = static_cast<AsyncCompositableChild*>(aActor);
MOZ_ASSERT(actor->GetAsyncID());
mImageContainers.Remove(actor->GetAsyncID());
AsyncCompositableChild::DestroyActor(aActor);
return true;
}
@ -1135,10 +1135,9 @@ mozilla::ipc::IPCResult
ImageBridgeChild::RecvDidComposite(InfallibleTArray<ImageCompositeNotification>&& aNotifications)
{
for (auto& n : aNotifications) {
ImageContainerChild* child =
static_cast<ImageContainerChild*>(n.imageContainerChild());
if (child) {
child->NotifyComposite(n);
RefPtr<ImageContainer> imageContainer = mImageContainers.Get(n.asyncCompositableID());
if (imageContainer) {
imageContainer->NotifyComposite(n);
}
}
return IPC_OK();

View File

@ -170,8 +170,7 @@ public:
virtual base::ProcessId GetParentPid() const override { return OtherPid(); }
PCompositableChild* AllocPCompositableChild(const TextureInfo& aInfo,
const uint64_t& aID,
PImageContainerChild* aChild) override;
const uint64_t& aID) override;
bool DeallocPCompositableChild(PCompositableChild* aActor) override;
virtual PTextureChild*
@ -393,6 +392,11 @@ private:
* It defer calling of TextureClient recycle callback.
*/
nsDataHashtable<nsUint64HashKey, RefPtr<TextureClient> > mTexturesWaitingRecycled;
/**
* Mapping from async compositable IDs to image containers.
*/
nsDataHashtable<nsUint64HashKey, RefPtr<ImageContainer>> mImageContainers;
};
} // namespace layers

View File

@ -239,19 +239,21 @@ mozilla::ipc::IPCResult ImageBridgeParent::RecvWillClose()
}
PCompositableParent*
ImageBridgeParent::AllocPCompositableParent(const TextureInfo& aInfo,
const uint64_t& aID,
PImageContainerParent* aImageContainer)
ImageBridgeParent::AllocPCompositableParent(const TextureInfo& aInfo, const uint64_t& aID)
{
PCompositableParent* actor = CompositableHost::CreateIPDLActor(this, aInfo, aImageContainer);
PCompositableParent* actor = CompositableHost::CreateIPDLActor(this, aInfo);
if (mCompositables.find(aID) != mCompositables.end()) {
NS_ERROR("Async compositable ID already exists");
return actor;
}
if (!aID) {
NS_ERROR("Expected non-zero async compositable ID");
return actor;
}
CompositableHost* host = CompositableHost::FromIPDLActor(actor);
host->SetAsyncID(aID);
host->SetAsyncRef(AsyncCompositableRef(OtherPid(), aID));
mCompositables[aID] = host;
return actor;
@ -260,7 +262,8 @@ ImageBridgeParent::AllocPCompositableParent(const TextureInfo& aInfo,
bool ImageBridgeParent::DeallocPCompositableParent(PCompositableParent* aActor)
{
if (CompositableHost* host = CompositableHost::FromIPDLActor(aActor)) {
mCompositables.erase(host->GetAsyncID());
const AsyncCompositableRef& ref = host->GetAsyncRef();
mCompositables.erase(ref.mAsyncId);
}
return CompositableHost::DestroyIPDLActor(aActor);
}
@ -316,20 +319,20 @@ ImageBridgeParent::SendAsyncMessage(const InfallibleTArray<AsyncParentMessageDat
class ProcessIdComparator
{
public:
bool Equals(const ImageCompositeNotification& aA,
const ImageCompositeNotification& aB) const
bool Equals(const ImageCompositeNotificationInfo& aA,
const ImageCompositeNotificationInfo& aB) const
{
return aA.imageContainerParent()->OtherPid() == aB.imageContainerParent()->OtherPid();
return aA.mImageBridgeProcessId == aB.mImageBridgeProcessId;
}
bool LessThan(const ImageCompositeNotification& aA,
const ImageCompositeNotification& aB) const
bool LessThan(const ImageCompositeNotificationInfo& aA,
const ImageCompositeNotificationInfo& aB) const
{
return aA.imageContainerParent()->OtherPid() < aB.imageContainerParent()->OtherPid();
return aA.mImageBridgeProcessId < aB.mImageBridgeProcessId;
}
};
/* static */ bool
ImageBridgeParent::NotifyImageComposites(nsTArray<ImageCompositeNotification>& aNotifications)
ImageBridgeParent::NotifyImageComposites(nsTArray<ImageCompositeNotificationInfo>& aNotifications)
{
// Group the notifications by destination process ID and then send the
// notifications in one message per group.
@ -338,13 +341,13 @@ ImageBridgeParent::NotifyImageComposites(nsTArray<ImageCompositeNotification>& a
bool ok = true;
while (i < aNotifications.Length()) {
AutoTArray<ImageCompositeNotification,1> notifications;
notifications.AppendElement(aNotifications[i]);
notifications.AppendElement(aNotifications[i].mNotification);
uint32_t end = i + 1;
MOZ_ASSERT(aNotifications[i].imageContainerParent());
ProcessId pid = aNotifications[i].imageContainerParent()->OtherPid();
MOZ_ASSERT(aNotifications[i].mNotification.asyncCompositableID());
ProcessId pid = aNotifications[i].mImageBridgeProcessId;
while (end < aNotifications.Length() &&
aNotifications[end].imageContainerParent()->OtherPid() == pid) {
notifications.AppendElement(aNotifications[end]);
aNotifications[end].mImageBridgeProcessId == pid) {
notifications.AppendElement(aNotifications[end].mNotification);
++end;
}
GetInstance(pid)->SendPendingAsyncMessages();

View File

@ -32,6 +32,8 @@ class Shmem;
namespace layers {
struct ImageCompositeNotificationInfo;
/**
* ImageBridgeParent is the manager Protocol of ImageContainerParent.
* It's purpose is mainly to setup the IPDL connection. Most of the
@ -79,8 +81,7 @@ public:
const uint64_t& aFwdTransactionId) override;
PCompositableParent* AllocPCompositableParent(const TextureInfo& aInfo,
const uint64_t& aID,
PImageContainerParent* aImageContainer) override;
const uint64_t& aID) override;
bool DeallocPCompositableParent(PCompositableParent* aActor) override;
virtual PTextureParent* AllocPTextureParent(const SurfaceDescriptor& aSharedData,
@ -121,7 +122,7 @@ public:
static ImageBridgeParent* GetInstance(ProcessId aId);
static bool NotifyImageComposites(nsTArray<ImageCompositeNotification>& aNotifications);
static bool NotifyImageComposites(nsTArray<ImageCompositeNotificationInfo>& aNotifications);
virtual bool UsesImageBridge() const override { return true; }

View File

@ -32,7 +32,7 @@ ImageContainerChild::NotifyComposite(const ImageCompositeNotification& aNotifica
MutexAutoLock lock(mLock);
if (mImageContainer) {
mImageContainer->NotifyCompositeInternal(aNotification);
mImageContainer->NotifyComposite(aNotification);
}
}

View File

@ -16,9 +16,6 @@ namespace layers {
ImageContainerParent::~ImageContainerParent()
{
while (!mImageHosts.IsEmpty()) {
mImageHosts[mImageHosts.Length() - 1]->SetImageContainer(nullptr);
}
}
mozilla::ipc::IPCResult ImageContainerParent::RecvAsyncDelete()

View File

@ -963,7 +963,7 @@ LayerTransactionParent::RecvForceComposite()
PCompositableParent*
LayerTransactionParent::AllocPCompositableParent(const TextureInfo& aInfo)
{
return CompositableHost::CreateIPDLActor(this, aInfo, 0);
return CompositableHost::CreateIPDLActor(this, aInfo);
}
bool

View File

@ -523,7 +523,7 @@ struct OpContentBufferSwap {
* image is composited by an ImageHost.
*/
struct ImageCompositeNotification {
PImageContainer imageContainer;
uint64_t asyncCompositableID;
TimeStamp imageTimeStamp;
TimeStamp firstCompositeTimeStamp;
uint32_t frameID;

View File

@ -55,9 +55,7 @@ parent:
// before sending closing the channel.
sync WillClose();
async PCompositable(TextureInfo aInfo,
uint64_t aId,
nullable PImageContainer aImageContainer);
async PCompositable(TextureInfo aInfo, uint64_t aId);
async PTexture(SurfaceDescriptor aSharedData, LayersBackend aBackend, TextureFlags aTextureFlags, uint64_t aSerial);
async PMediaSystemResourceManager();
async PImageContainer();