Skip to content

Commit

Permalink
Bug 1067455 - Reduce Fence::merge() call on compositor thread r=nical
Browse files Browse the repository at this point in the history
  • Loading branch information
Sotaro Ikeda committed Oct 6, 2014
1 parent 464da0f commit bae6e43
Show file tree
Hide file tree
Showing 15 changed files with 272 additions and 99 deletions.
6 changes: 6 additions & 0 deletions gfx/layers/Compositor.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "mozilla/gfx/Rect.h" // for Rect, IntRect
#include "mozilla/gfx/Types.h" // for Float
#include "mozilla/layers/CompositorTypes.h" // for DiagnosticTypes, etc
#include "mozilla/layers/FenceUtils.h" // for FenceHandle
#include "mozilla/layers/LayersTypes.h" // for LayersBackend
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
#include "nsRegion.h"
Expand Down Expand Up @@ -353,6 +354,11 @@ class Compositor

virtual void SetFBAcquireFence(Layer* aLayer) {}

virtual FenceHandle GetReleaseFence()
{
return FenceHandle();
}

/**
* Post-rendering stuff if the rendering is done outside of this Compositor
* e.g., by Composer2D.
Expand Down
2 changes: 1 addition & 1 deletion gfx/layers/client/TextureClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ class TextureClient

virtual void SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle)
{
mReleaseFenceHandle = aReleaseFenceHandle;
mReleaseFenceHandle.Merge(aReleaseFenceHandle);
}

const FenceHandle& GetReleaseFenceHandle() const
Expand Down
33 changes: 0 additions & 33 deletions gfx/layers/composite/TextureHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,6 @@ class TextureParent : public PTextureParent

void CompositorRecycle();

void SendFenceHandleIfPresent();

virtual bool RecvClientRecycle() MOZ_OVERRIDE;

virtual bool RecvClearTextureHostSync() MOZ_OVERRIDE;
Expand Down Expand Up @@ -147,14 +145,6 @@ TextureHost::GetIPDLActor()
return mActor;
}

// static
void
TextureHost::SendFenceHandleIfPresent(PTextureParent* actor)
{
TextureParent* parent = static_cast<TextureParent*>(actor);
parent->SendFenceHandleIfPresent();
}

FenceHandle
TextureHost::GetAndResetReleaseFenceHandle()
{
Expand Down Expand Up @@ -714,7 +704,6 @@ void
TextureParent::CompositorRecycle()
{
mTextureHost->ClearRecycleCallback();
SendFenceHandleIfPresent();

if (mTextureHost->GetFlags() & TextureFlags::RECYCLE) {
mozilla::unused << SendCompositorRecycle();
Expand All @@ -724,28 +713,6 @@ TextureParent::CompositorRecycle()
}
}

void
TextureParent::SendFenceHandleIfPresent()
{
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
if (mTextureHost) {
TextureHostOGL* hostOGL = mTextureHost->AsHostOGL();
if (!hostOGL) {
return;
}
android::sp<android::Fence> fence = hostOGL->GetAndResetReleaseFence();
if (fence.get() && fence->isValid()) {
// HWC might not provide Fence.
// In this case, HWC implicitly handles buffer's fence.

FenceHandle handle = FenceHandle(fence);
RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(handle);
mCompositableManager->SendFenceHandle(tracker, this, handle);
}
}
#endif
}

bool
TextureParent::RecvClientRecycle()
{
Expand Down
2 changes: 0 additions & 2 deletions gfx/layers/composite/TextureHost.h
Original file line number Diff line number Diff line change
Expand Up @@ -421,8 +421,6 @@ class TextureHost
*/
PTextureParent* GetIPDLActor();

static void SendFenceHandleIfPresent(PTextureParent* actor);

FenceHandle GetAndResetReleaseFenceHandle();

/**
Expand Down
43 changes: 40 additions & 3 deletions gfx/layers/ipc/CompositableTransactionParent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
MOZ_ASSERT(tex.get());
compositable->RemoveTextureHost(tex);
// send FenceHandle if present.
TextureHost::SendFenceHandleIfPresent(op.textureParent());
SendFenceHandleIfPresent(op.textureParent(), compositable);
break;
}
case CompositableOperation::TOpRemoveTextureAsync: {
Expand All @@ -179,7 +179,8 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
GetChildProcessId(),
op.holderId(),
op.transactionId(),
op.textureParent());
op.textureParent(),
compositable);

// If the message is recievied via PLayerTransaction,
// Send message back via PImageBridge.
Expand All @@ -190,7 +191,7 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
op.transactionId()));
} else {
// send FenceHandle if present.
TextureHost::SendFenceHandleIfPresent(op.textureParent());
SendFenceHandleIfPresent(op.textureParent(), compositable);

ReplyRemoveTexture(OpReplyRemoveTexture(false, // isMain
op.holderId(),
Expand Down Expand Up @@ -258,6 +259,42 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
return true;
}

void
CompositableParentManager::SendPendingAsyncMessges()
{
if (mPendingAsyncMessage.empty()) {
return;
}

// Some type of AsyncParentMessageData message could have
// one file descriptor (e.g. OpDeliverFence).
// A number of file descriptors per gecko ipc message have a limitation
// on OS_POSIX (MACOSX or LINUX).
#if defined(OS_POSIX)
static const uint32_t kMaxMessageNumber = FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE;
#else
// default number that works everywhere else
static const uint32_t kMaxMessageNumber = 250;
#endif

InfallibleTArray<AsyncParentMessageData> messages;
messages.SetCapacity(mPendingAsyncMessage.size());
for (size_t i = 0; i < mPendingAsyncMessage.size(); i++) {
messages.AppendElement(mPendingAsyncMessage[i]);
// Limit maximum number of messages.
if (messages.Length() >= kMaxMessageNumber) {
SendAsyncMessage(messages);
// Initialize Messages.
messages.Clear();
}
}

if (messages.Length() > 0) {
SendAsyncMessage(messages);
}
mPendingAsyncMessage.clear();
}

} // namespace
} // namespace

6 changes: 6 additions & 0 deletions gfx/layers/ipc/CompositableTransactionParent.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,17 @@ class CompositableParentManager : public ISurfaceAllocator
, public AsyncTransactionTrackersHolder
{
public:
virtual void SendFenceHandleIfPresent(PTextureParent* aTexture,
CompositableHost* aCompositableHost) = 0;

virtual void SendFenceHandle(AsyncTransactionTracker* aTracker,
PTextureParent* aTexture,
const FenceHandle& aFence) = 0;

virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) = 0;

void SendPendingAsyncMessges();

/**
* Get child side's process Id.
*/
Expand All @@ -57,6 +62,7 @@ class CompositableParentManager : public ISurfaceAllocator

virtual void ReplyRemoveTexture(const OpReplyRemoveTexture& aReply) {}

std::vector<AsyncParentMessageData> mPendingAsyncMessage;
};

} // namespace
Expand Down
1 change: 1 addition & 0 deletions gfx/layers/ipc/FenceUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct FenceHandle {
explicit FenceHandle(const FenceHandleFromChild& aFenceHandle) {}
bool operator==(const FenceHandle&) const { return false; }
bool IsValid() const { return false; }
void Merge(const FenceHandle& aFenceHandle) {}
};

struct FenceHandleFromChild {
Expand Down
42 changes: 40 additions & 2 deletions gfx/layers/ipc/FenceUtilsGonk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ ParamTraits<FenceHandle>::Write(Message* aMsg,
flattenable->flatten(data, nbytes, fds, nfds);
#endif
aMsg->WriteSize(nbytes);
aMsg->WriteSize(nfds);
aMsg->WriteBytes(data, nbytes);
for (size_t n = 0; n < nfds; ++n) {
// These buffers can't die in transit because they're created
Expand All @@ -63,14 +64,20 @@ ParamTraits<FenceHandle>::Read(const Message* aMsg,
void** aIter, paramType* aResult)
{
size_t nbytes;
size_t nfds;
const char* data;

if (!aMsg->ReadSize(aIter, &nbytes) ||
!aMsg->ReadSize(aIter, &nfds) ||
!aMsg->ReadBytes(aIter, &data, nbytes)) {
return false;
}

size_t nfds = aMsg->num_fds();
// Check if nfds is correct.
// aMsg->num_fds() could include fds of another ParamTraits<>s.
if (nfds > aMsg->num_fds()) {
return false;
}
int fds[nfds];

for (size_t n = 0; n < nfds; ++n) {
Expand Down Expand Up @@ -138,6 +145,7 @@ ParamTraits<FenceHandleFromChild>::Write(Message* aMsg,
flattenable->flatten(data, nbytes, fds, nfds);
#endif
aMsg->WriteSize(nbytes);
aMsg->WriteSize(nfds);
aMsg->WriteBytes(data, nbytes);
for (size_t n = 0; n < nfds; ++n) {
// If the Fence was shared cross-process, SCM_RIGHTS does
Expand All @@ -161,14 +169,20 @@ ParamTraits<FenceHandleFromChild>::Read(const Message* aMsg,
void** aIter, paramType* aResult)
{
size_t nbytes;
size_t nfds;
const char* data;

if (!aMsg->ReadSize(aIter, &nbytes) ||
!aMsg->ReadSize(aIter, &nfds) ||
!aMsg->ReadBytes(aIter, &data, nbytes)) {
return false;
}

size_t nfds = aMsg->num_fds();
// Check if nfds is correct.
// aMsg->num_fds() could include fds of another ParamTraits<>s.
if (nfds > aMsg->num_fds()) {
return false;
}
int fds[nfds];

for (size_t n = 0; n < nfds; ++n) {
Expand Down Expand Up @@ -211,6 +225,30 @@ FenceHandle::FenceHandle(const FenceHandleFromChild& aFenceHandle) {
mFence = aFenceHandle.mFence;
}

void
FenceHandle::Merge(const FenceHandle& aFenceHandle)
{
if (!aFenceHandle.IsValid()) {
return;
}

if (!IsValid()) {
mFence = aFenceHandle.mFence;
} else {
android::sp<android::Fence> mergedFence = android::Fence::merge(
android::String8::format("FenceHandle"),
mFence, aFenceHandle.mFence);
if (!mergedFence.get()) {
// synchronization is broken, the best we can do is hope fences
// signal in order so the new fence will act like a union.
// This error handling is same as android::ConsumerBase does.
mFence = aFenceHandle.mFence;
return;
}
mFence = mergedFence;
}
}

FenceHandleFromChild::FenceHandleFromChild(const sp<Fence>& aFence)
: mFence(aFence)
{
Expand Down
10 changes: 6 additions & 4 deletions gfx/layers/ipc/FenceUtilsGonk.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ struct FenceHandle {

FenceHandle()
{ }
FenceHandle(const android::sp<Fence>& aFence);
explicit FenceHandle(const android::sp<Fence>& aFence);

FenceHandle(const FenceHandleFromChild& aFenceHandle);
explicit FenceHandle(const FenceHandleFromChild& aFenceHandle);

bool operator==(const FenceHandle& aOther) const {
return mFence.get() == aOther.mFence.get();
Expand All @@ -36,6 +36,8 @@ struct FenceHandle {
return mFence.get() && mFence->isValid();
}

void Merge(const FenceHandle& aFenceHandle);

android::sp<Fence> mFence;
};

Expand All @@ -44,9 +46,9 @@ struct FenceHandleFromChild {

FenceHandleFromChild()
{ }
FenceHandleFromChild(const android::sp<Fence>& aFence);
explicit FenceHandleFromChild(const android::sp<Fence>& aFence);

FenceHandleFromChild(const FenceHandle& aFence) {
explicit FenceHandleFromChild(const FenceHandle& aFence) {
mFence = aFence.mFence;
}

Expand Down
Loading

0 comments on commit bae6e43

Please sign in to comment.