Bug 1067455 - Reduce Fence::merge() call on compositor thread r=nical

This commit is contained in:
Sotaro Ikeda 2014-10-06 15:45:03 -07:00
Родитель 464da0f9c2
Коммит bae6e432e4
15 изменённых файлов: 274 добавлений и 101 удалений

Просмотреть файл

@ -13,6 +13,7 @@
#include "mozilla/gfx/Rect.h" // for Rect, IntRect #include "mozilla/gfx/Rect.h" // for Rect, IntRect
#include "mozilla/gfx/Types.h" // for Float #include "mozilla/gfx/Types.h" // for Float
#include "mozilla/layers/CompositorTypes.h" // for DiagnosticTypes, etc #include "mozilla/layers/CompositorTypes.h" // for DiagnosticTypes, etc
#include "mozilla/layers/FenceUtils.h" // for FenceHandle
#include "mozilla/layers/LayersTypes.h" // for LayersBackend #include "mozilla/layers/LayersTypes.h" // for LayersBackend
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
#include "nsRegion.h" #include "nsRegion.h"
@ -353,6 +354,11 @@ public:
virtual void SetFBAcquireFence(Layer* aLayer) {} virtual void SetFBAcquireFence(Layer* aLayer) {}
virtual FenceHandle GetReleaseFence()
{
return FenceHandle();
}
/** /**
* Post-rendering stuff if the rendering is done outside of this Compositor * Post-rendering stuff if the rendering is done outside of this Compositor
* e.g., by Composer2D. * e.g., by Composer2D.

Просмотреть файл

@ -358,7 +358,7 @@ public:
virtual void SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle) virtual void SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle)
{ {
mReleaseFenceHandle = aReleaseFenceHandle; mReleaseFenceHandle.Merge(aReleaseFenceHandle);
} }
const FenceHandle& GetReleaseFenceHandle() const const FenceHandle& GetReleaseFenceHandle() const

Просмотреть файл

@ -80,8 +80,6 @@ public:
void CompositorRecycle(); void CompositorRecycle();
void SendFenceHandleIfPresent();
virtual bool RecvClientRecycle() MOZ_OVERRIDE; virtual bool RecvClientRecycle() MOZ_OVERRIDE;
virtual bool RecvClearTextureHostSync() MOZ_OVERRIDE; virtual bool RecvClearTextureHostSync() MOZ_OVERRIDE;
@ -147,14 +145,6 @@ TextureHost::GetIPDLActor()
return mActor; return mActor;
} }
// static
void
TextureHost::SendFenceHandleIfPresent(PTextureParent* actor)
{
TextureParent* parent = static_cast<TextureParent*>(actor);
parent->SendFenceHandleIfPresent();
}
FenceHandle FenceHandle
TextureHost::GetAndResetReleaseFenceHandle() TextureHost::GetAndResetReleaseFenceHandle()
{ {
@ -714,7 +704,6 @@ void
TextureParent::CompositorRecycle() TextureParent::CompositorRecycle()
{ {
mTextureHost->ClearRecycleCallback(); mTextureHost->ClearRecycleCallback();
SendFenceHandleIfPresent();
if (mTextureHost->GetFlags() & TextureFlags::RECYCLE) { if (mTextureHost->GetFlags() & TextureFlags::RECYCLE) {
mozilla::unused << SendCompositorRecycle(); mozilla::unused << SendCompositorRecycle();
@ -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 bool
TextureParent::RecvClientRecycle() TextureParent::RecvClientRecycle()
{ {

Просмотреть файл

@ -421,8 +421,6 @@ public:
*/ */
PTextureParent* GetIPDLActor(); PTextureParent* GetIPDLActor();
static void SendFenceHandleIfPresent(PTextureParent* actor);
FenceHandle GetAndResetReleaseFenceHandle(); FenceHandle GetAndResetReleaseFenceHandle();
/** /**

Просмотреть файл

@ -162,7 +162,7 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
MOZ_ASSERT(tex.get()); MOZ_ASSERT(tex.get());
compositable->RemoveTextureHost(tex); compositable->RemoveTextureHost(tex);
// send FenceHandle if present. // send FenceHandle if present.
TextureHost::SendFenceHandleIfPresent(op.textureParent()); SendFenceHandleIfPresent(op.textureParent(), compositable);
break; break;
} }
case CompositableOperation::TOpRemoveTextureAsync: { case CompositableOperation::TOpRemoveTextureAsync: {
@ -179,7 +179,8 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
GetChildProcessId(), GetChildProcessId(),
op.holderId(), op.holderId(),
op.transactionId(), op.transactionId(),
op.textureParent()); op.textureParent(),
compositable);
// If the message is recievied via PLayerTransaction, // If the message is recievied via PLayerTransaction,
// Send message back via PImageBridge. // Send message back via PImageBridge.
@ -190,7 +191,7 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
op.transactionId())); op.transactionId()));
} else { } else {
// send FenceHandle if present. // send FenceHandle if present.
TextureHost::SendFenceHandleIfPresent(op.textureParent()); SendFenceHandleIfPresent(op.textureParent(), compositable);
ReplyRemoveTexture(OpReplyRemoveTexture(false, // isMain ReplyRemoveTexture(OpReplyRemoveTexture(false, // isMain
op.holderId(), op.holderId(),
@ -258,6 +259,42 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
return true; 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
} // namespace } // namespace

Просмотреть файл

@ -30,12 +30,17 @@ class CompositableParentManager : public ISurfaceAllocator
, public AsyncTransactionTrackersHolder , public AsyncTransactionTrackersHolder
{ {
public: public:
virtual void SendFenceHandleIfPresent(PTextureParent* aTexture,
CompositableHost* aCompositableHost) = 0;
virtual void SendFenceHandle(AsyncTransactionTracker* aTracker, virtual void SendFenceHandle(AsyncTransactionTracker* aTracker,
PTextureParent* aTexture, PTextureParent* aTexture,
const FenceHandle& aFence) = 0; const FenceHandle& aFence) = 0;
virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) = 0; virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) = 0;
void SendPendingAsyncMessges();
/** /**
* Get child side's process Id. * Get child side's process Id.
*/ */
@ -57,6 +62,7 @@ protected:
virtual void ReplyRemoveTexture(const OpReplyRemoveTexture& aReply) {} virtual void ReplyRemoveTexture(const OpReplyRemoveTexture& aReply) {}
std::vector<AsyncParentMessageData> mPendingAsyncMessage;
}; };
} // namespace } // namespace

Просмотреть файл

@ -26,6 +26,7 @@ struct FenceHandle {
explicit FenceHandle(const FenceHandleFromChild& aFenceHandle) {} explicit FenceHandle(const FenceHandleFromChild& aFenceHandle) {}
bool operator==(const FenceHandle&) const { return false; } bool operator==(const FenceHandle&) const { return false; }
bool IsValid() const { return false; } bool IsValid() const { return false; }
void Merge(const FenceHandle& aFenceHandle) {}
}; };
struct FenceHandleFromChild { struct FenceHandleFromChild {

Просмотреть файл

@ -49,6 +49,7 @@ ParamTraits<FenceHandle>::Write(Message* aMsg,
flattenable->flatten(data, nbytes, fds, nfds); flattenable->flatten(data, nbytes, fds, nfds);
#endif #endif
aMsg->WriteSize(nbytes); aMsg->WriteSize(nbytes);
aMsg->WriteSize(nfds);
aMsg->WriteBytes(data, nbytes); aMsg->WriteBytes(data, nbytes);
for (size_t n = 0; n < nfds; ++n) { for (size_t n = 0; n < nfds; ++n) {
// These buffers can't die in transit because they're created // These buffers can't die in transit because they're created
@ -63,14 +64,20 @@ ParamTraits<FenceHandle>::Read(const Message* aMsg,
void** aIter, paramType* aResult) void** aIter, paramType* aResult)
{ {
size_t nbytes; size_t nbytes;
size_t nfds;
const char* data; const char* data;
if (!aMsg->ReadSize(aIter, &nbytes) || if (!aMsg->ReadSize(aIter, &nbytes) ||
!aMsg->ReadSize(aIter, &nfds) ||
!aMsg->ReadBytes(aIter, &data, nbytes)) { !aMsg->ReadBytes(aIter, &data, nbytes)) {
return false; 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]; int fds[nfds];
for (size_t n = 0; n < nfds; ++n) { for (size_t n = 0; n < nfds; ++n) {
@ -138,6 +145,7 @@ ParamTraits<FenceHandleFromChild>::Write(Message* aMsg,
flattenable->flatten(data, nbytes, fds, nfds); flattenable->flatten(data, nbytes, fds, nfds);
#endif #endif
aMsg->WriteSize(nbytes); aMsg->WriteSize(nbytes);
aMsg->WriteSize(nfds);
aMsg->WriteBytes(data, nbytes); aMsg->WriteBytes(data, nbytes);
for (size_t n = 0; n < nfds; ++n) { for (size_t n = 0; n < nfds; ++n) {
// If the Fence was shared cross-process, SCM_RIGHTS does // If the Fence was shared cross-process, SCM_RIGHTS does
@ -161,14 +169,20 @@ ParamTraits<FenceHandleFromChild>::Read(const Message* aMsg,
void** aIter, paramType* aResult) void** aIter, paramType* aResult)
{ {
size_t nbytes; size_t nbytes;
size_t nfds;
const char* data; const char* data;
if (!aMsg->ReadSize(aIter, &nbytes) || if (!aMsg->ReadSize(aIter, &nbytes) ||
!aMsg->ReadSize(aIter, &nfds) ||
!aMsg->ReadBytes(aIter, &data, nbytes)) { !aMsg->ReadBytes(aIter, &data, nbytes)) {
return false; 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]; int fds[nfds];
for (size_t n = 0; n < nfds; ++n) { for (size_t n = 0; n < nfds; ++n) {
@ -211,6 +225,30 @@ FenceHandle::FenceHandle(const FenceHandleFromChild& aFenceHandle) {
mFence = aFenceHandle.mFence; 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) FenceHandleFromChild::FenceHandleFromChild(const sp<Fence>& aFence)
: mFence(aFence) : mFence(aFence)
{ {

Просмотреть файл

@ -23,9 +23,9 @@ struct FenceHandle {
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 { bool operator==(const FenceHandle& aOther) const {
return mFence.get() == aOther.mFence.get(); return mFence.get() == aOther.mFence.get();
@ -36,6 +36,8 @@ struct FenceHandle {
return mFence.get() && mFence->isValid(); return mFence.get() && mFence->isValid();
} }
void Merge(const FenceHandle& aFenceHandle);
android::sp<Fence> mFence; android::sp<Fence> mFence;
}; };
@ -44,9 +46,9 @@ struct FenceHandleFromChild {
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; mFence = aFence.mFence;
} }

Просмотреть файл

@ -96,9 +96,25 @@ ImageBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
NewRunnableMethod(this, &ImageBridgeParent::DeferredDestroy)); NewRunnableMethod(this, &ImageBridgeParent::DeferredDestroy));
} }
class MOZ_STACK_CLASS AutoImageBridgeParentAsyncMessageSender
{
public:
explicit AutoImageBridgeParentAsyncMessageSender(ImageBridgeParent* aImageBridge)
: mImageBridge(aImageBridge) {}
~AutoImageBridgeParentAsyncMessageSender()
{
mImageBridge->SendPendingAsyncMessges();
}
private:
ImageBridgeParent* mImageBridge;
};
bool bool
ImageBridgeParent::RecvUpdate(const EditArray& aEdits, EditReplyArray* aReply) ImageBridgeParent::RecvUpdate(const EditArray& aEdits, EditReplyArray* aReply)
{ {
AutoImageBridgeParentAsyncMessageSender autoAsyncMessageSender(this);
// If we don't actually have a compositor, then don't bother // If we don't actually have a compositor, then don't bother
// creating any textures. // creating any textures.
if (Compositor::GetBackend() == LayersBackend::LAYERS_NONE) { if (Compositor::GetBackend() == LayersBackend::LAYERS_NONE) {
@ -336,9 +352,7 @@ bool ImageBridgeParent::IsSameProcess() const
void void
ImageBridgeParent::ReplyRemoveTexture(const OpReplyRemoveTexture& aReply) ImageBridgeParent::ReplyRemoveTexture(const OpReplyRemoveTexture& aReply)
{ {
InfallibleTArray<AsyncParentMessageData> messages; mPendingAsyncMessage.push_back(aReply);
messages.AppendElement(aReply);
mozilla::unused << SendParentAsyncMessages(messages);
} }
/*static*/ void /*static*/ void
@ -352,35 +366,80 @@ ImageBridgeParent::ReplyRemoveTexture(base::ProcessId aChildProcessId,
imageBridge->ReplyRemoveTexture(aReply); imageBridge->ReplyRemoveTexture(aReply);
} }
/*static*/ void void
ImageBridgeParent::SendFenceHandleToTrackerIfPresent(uint64_t aDestHolderId, ImageBridgeParent::SendFenceHandleIfPresent(PTextureParent* aTexture,
uint64_t aTransactionId, CompositableHost* aCompositableHost)
PTextureParent* aTexture)
{ {
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture); RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
if (!texture) { if (!texture) {
return; return;
} }
// Send a ReleaseFence of CompositorOGL.
if (aCompositableHost && aCompositableHost->GetCompositor()) {
FenceHandle fence = aCompositableHost->GetCompositor()->GetReleaseFence();
if (fence.IsValid()) {
RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(fence);
HoldUntilComplete(tracker);
mPendingAsyncMessage.push_back(OpDeliverFence(tracker->GetId(),
aTexture, nullptr,
fence));
}
}
// Send a ReleaseFence that is set by HwcComposer2D.
FenceHandle fence = texture->GetAndResetReleaseFenceHandle(); FenceHandle fence = texture->GetAndResetReleaseFenceHandle();
if (!fence.IsValid()) { if (fence.IsValid()) {
RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(fence);
HoldUntilComplete(tracker);
mPendingAsyncMessage.push_back(OpDeliverFence(tracker->GetId(),
aTexture, nullptr,
fence));
}
}
void
ImageBridgeParent::SendFenceHandleToTrackerIfPresent(uint64_t aDestHolderId,
uint64_t aTransactionId,
PTextureParent* aTexture,
CompositableHost* aCompositableHost)
{
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
if (!texture) {
return; return;
} }
RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(fence); // Send a ReleaseFence of CompositorOGL.
HoldUntilComplete(tracker); if (aCompositableHost && aCompositableHost->GetCompositor()) {
InfallibleTArray<AsyncParentMessageData> messages; FenceHandle fence = aCompositableHost->GetCompositor()->GetReleaseFence();
messages.AppendElement(OpDeliverFenceToTracker(tracker->GetId(), if (fence.IsValid()) {
aDestHolderId, RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(fence);
aTransactionId, HoldUntilComplete(tracker);
fence)); mPendingAsyncMessage.push_back(OpDeliverFenceToTracker(tracker->GetId(),
mozilla::unused << SendParentAsyncMessages(messages); aDestHolderId,
aTransactionId,
fence));
}
}
// Send a ReleaseFence that is set by HwcComposer2D.
FenceHandle fence = texture->GetAndResetReleaseFenceHandle();
if (fence.IsValid()) {
RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(fence);
HoldUntilComplete(tracker);
mPendingAsyncMessage.push_back(OpDeliverFenceToTracker(tracker->GetId(),
aDestHolderId,
aTransactionId,
fence));
}
} }
/*static*/ void /*static*/ void
ImageBridgeParent::SendFenceHandleToTrackerIfPresent(base::ProcessId aChildProcessId, ImageBridgeParent::SendFenceHandleToTrackerIfPresent(base::ProcessId aChildProcessId,
uint64_t aDestHolderId, uint64_t aDestHolderId,
uint64_t aTransactionId, uint64_t aTransactionId,
PTextureParent* aTexture) PTextureParent* aTexture,
CompositableHost* aCompositableHost)
{ {
ImageBridgeParent* imageBridge = ImageBridgeParent::GetInstance(aChildProcessId); ImageBridgeParent* imageBridge = ImageBridgeParent::GetInstance(aChildProcessId);
if (!imageBridge) { if (!imageBridge) {
@ -388,9 +447,21 @@ ImageBridgeParent::SendFenceHandleToTrackerIfPresent(base::ProcessId aChildProce
} }
imageBridge->SendFenceHandleToTrackerIfPresent(aDestHolderId, imageBridge->SendFenceHandleToTrackerIfPresent(aDestHolderId,
aTransactionId, aTransactionId,
aTexture); aTexture,
aCompositableHost);
} }
/*static*/ void
ImageBridgeParent::SendPendingAsyncMessges(base::ProcessId aChildProcessId)
{
#ifdef MOZ_WIDGET_GONK
ImageBridgeParent* imageBridge = ImageBridgeParent::GetInstance(aChildProcessId);
if (!imageBridge) {
return;
}
imageBridge->SendPendingAsyncMessges();
#endif
}
} // layers } // layers
} // mozilla } // mozilla

Просмотреть файл

@ -56,6 +56,9 @@ public:
Create(Transport* aTransport, ProcessId aChildProcessId); Create(Transport* aTransport, ProcessId aChildProcessId);
// CompositableParentManager // CompositableParentManager
virtual void SendFenceHandleIfPresent(PTextureParent* aTexture,
CompositableHost* aCompositableHost) MOZ_OVERRIDE;
virtual void SendFenceHandle(AsyncTransactionTracker* aTracker, virtual void SendFenceHandle(AsyncTransactionTracker* aTracker,
PTextureParent* aTexture, PTextureParent* aTexture,
const FenceHandle& aFence) MOZ_OVERRIDE; const FenceHandle& aFence) MOZ_OVERRIDE;
@ -122,12 +125,17 @@ public:
void SendFenceHandleToTrackerIfPresent(uint64_t aDestHolderId, void SendFenceHandleToTrackerIfPresent(uint64_t aDestHolderId,
uint64_t aTransactionId, uint64_t aTransactionId,
PTextureParent* aTexture); PTextureParent* aTexture,
CompositableHost* aCompositableHost);
static void SendFenceHandleToTrackerIfPresent(base::ProcessId aChildProcessId, static void SendFenceHandleToTrackerIfPresent(base::ProcessId aChildProcessId,
uint64_t aDestHolderId, uint64_t aDestHolderId,
uint64_t aTransactionId, uint64_t aTransactionId,
PTextureParent* aTexture); PTextureParent* aTexture,
CompositableHost* aCompositableHost);
using CompositableParentManager::SendPendingAsyncMessges;
static void SendPendingAsyncMessges(base::ProcessId aChildProcessId);
static ImageBridgeParent* GetInstance(ProcessId aId); static ImageBridgeParent* GetInstance(ProcessId aId);

Просмотреть файл

@ -18,6 +18,7 @@
#include "mozilla/layers/ColorLayerComposite.h" #include "mozilla/layers/ColorLayerComposite.h"
#include "mozilla/layers/Compositor.h" // for Compositor #include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/ContainerLayerComposite.h" #include "mozilla/layers/ContainerLayerComposite.h"
#include "mozilla/layers/ImageBridgeParent.h" // for ImageBridgeParent
#include "mozilla/layers/ImageLayerComposite.h" #include "mozilla/layers/ImageLayerComposite.h"
#include "mozilla/layers/LayerManagerComposite.h" #include "mozilla/layers/LayerManagerComposite.h"
#include "mozilla/layers/LayersMessages.h" // for EditReply, etc #include "mozilla/layers/LayersMessages.h" // for EditReply, etc
@ -192,6 +193,21 @@ LayerTransactionParent::RecvUpdateNoSwap(const InfallibleTArray<Edit>& cset,
aTransactionStart, nullptr); aTransactionStart, nullptr);
} }
class MOZ_STACK_CLASS AutoLayerTransactionParentAsyncMessageSender
{
public:
explicit AutoLayerTransactionParentAsyncMessageSender(LayerTransactionParent* aLayerTransaction)
: mLayerTransaction(aLayerTransaction) {}
~AutoLayerTransactionParentAsyncMessageSender()
{
mLayerTransaction->SendPendingAsyncMessges();
ImageBridgeParent::SendPendingAsyncMessges(mLayerTransaction->GetChildProcessId());
}
private:
LayerTransactionParent* mLayerTransaction;
};
bool bool
LayerTransactionParent::RecvUpdate(const InfallibleTArray<Edit>& cset, LayerTransactionParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
const uint64_t& aTransactionId, const uint64_t& aTransactionId,
@ -223,6 +239,7 @@ LayerTransactionParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
} }
EditReplyVector replyv; EditReplyVector replyv;
AutoLayerTransactionParentAsyncMessageSender autoAsyncMessageSender(this);
{ {
AutoResolveRefLayers resolve(mShadowLayersManager->GetCompositionManager(this)); AutoResolveRefLayers resolve(mShadowLayersManager->GetCompositionManager(this));
@ -890,6 +907,38 @@ bool LayerTransactionParent::IsSameProcess() const
return OtherProcess() == ipc::kInvalidProcessHandle; return OtherProcess() == ipc::kInvalidProcessHandle;
} }
void
LayerTransactionParent::SendFenceHandleIfPresent(PTextureParent* aTexture,
CompositableHost* aCompositableHost)
{
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
if (!texture) {
return;
}
// Send a ReleaseFence of CompositorOGL.
if (aCompositableHost && aCompositableHost->GetCompositor()) {
FenceHandle fence = aCompositableHost->GetCompositor()->GetReleaseFence();
if (fence.IsValid()) {
RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(fence);
HoldUntilComplete(tracker);
mPendingAsyncMessage.push_back(OpDeliverFence(tracker->GetId(),
aTexture, nullptr,
fence));
}
}
// Send a ReleaseFence that is set by HwcComposer2D.
FenceHandle fence = texture->GetAndResetReleaseFenceHandle();
if (fence.IsValid()) {
RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(fence);
HoldUntilComplete(tracker);
mPendingAsyncMessage.push_back(OpDeliverFence(tracker->GetId(),
aTexture, nullptr,
fence));
}
}
void void
LayerTransactionParent::SendFenceHandle(AsyncTransactionTracker* aTracker, LayerTransactionParent::SendFenceHandle(AsyncTransactionTracker* aTracker,
PTextureParent* aTexture, PTextureParent* aTexture,

Просмотреть файл

@ -86,6 +86,9 @@ public:
void SetPendingTransactionId(uint64_t aId) { mPendingTransaction = aId; } void SetPendingTransactionId(uint64_t aId) { mPendingTransaction = aId; }
// CompositableParentManager // CompositableParentManager
virtual void SendFenceHandleIfPresent(PTextureParent* aTexture,
CompositableHost* aCompositableHost) MOZ_OVERRIDE;
virtual void SendFenceHandle(AsyncTransactionTracker* aTracker, virtual void SendFenceHandle(AsyncTransactionTracker* aTracker,
PTextureParent* aTexture, PTextureParent* aTexture,
const FenceHandle& aFence) MOZ_OVERRIDE; const FenceHandle& aFence) MOZ_OVERRIDE;

Просмотреть файл

@ -1398,49 +1398,33 @@ CompositorOGL::SetFBAcquireFence(Layer* aLayer)
return; return;
} }
const nsIntRegion& visibleRegion = aLayer->GetEffectiveVisibleRegion(); android::sp<android::Fence> fence = new android::Fence(GetGonkDisplay()->GetPrevFBAcquireFd());
if (visibleRegion.IsEmpty()) { if (fence.get() && fence->isValid()) {
return; FenceHandle handle = FenceHandle(fence);
mReleaseFenceHandle.Merge(handle);
} }
// Set FBAcquireFence on ContainerLayer's childs
ContainerLayer* container = aLayer->AsContainerLayer();
if (container) {
for (Layer* child = container->GetFirstChild(); child; child = child->GetNextSibling()) {
SetFBAcquireFence(child);
}
return;
}
// Set FBAcquireFence as tiles' ReleaseFence on TiledLayerComposer.
TiledLayerComposer* composer = nullptr;
LayerComposite* shadow = aLayer->AsLayerComposite();
// Only ask for the composer if we have a compositable host. Timing
// may make it so that we don't - see bug 1000634.
if (shadow && shadow->GetCompositableHost()) {
composer = shadow->GetTiledLayerComposer();
if (composer) {
composer->SetReleaseFence(new android::Fence(GetGonkDisplay()->GetPrevFBAcquireFd()));
return;
}
}
// Set FBAcquireFence as layer buffer's ReleaseFence
LayerRenderState state = aLayer->GetRenderState();
if (!state.mTexture) {
return;
}
TextureHostOGL* texture = state.mTexture->AsHostOGL();
if (!texture) {
return;
}
texture->SetReleaseFence(new android::Fence(GetGonkDisplay()->GetPrevFBAcquireFd()));
} }
FenceHandle
CompositorOGL::GetReleaseFence()
{
if (!mReleaseFenceHandle.IsValid()) {
return FenceHandle();
}
return FenceHandle(new android::Fence(mReleaseFenceHandle.mFence->dup()));
}
#else #else
void void
CompositorOGL::SetFBAcquireFence(Layer* aLayer) CompositorOGL::SetFBAcquireFence(Layer* aLayer)
{ {
} }
FenceHandle
CompositorOGL::GetReleaseFence()
{
return FenceHandle();
}
#endif #endif
void void

Просмотреть файл

@ -209,6 +209,7 @@ public:
virtual void EndFrame() MOZ_OVERRIDE; virtual void EndFrame() MOZ_OVERRIDE;
virtual void SetFBAcquireFence(Layer* aLayer) MOZ_OVERRIDE; virtual void SetFBAcquireFence(Layer* aLayer) MOZ_OVERRIDE;
virtual FenceHandle GetReleaseFence() MOZ_OVERRIDE;
virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) MOZ_OVERRIDE; virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) MOZ_OVERRIDE;
virtual void AbortFrame() MOZ_OVERRIDE; virtual void AbortFrame() MOZ_OVERRIDE;
@ -393,6 +394,8 @@ private:
* FlipY for the y-flipping calculation. * FlipY for the y-flipping calculation.
*/ */
GLint mHeight; GLint mHeight;
FenceHandle mReleaseFenceHandle;
}; };
} }