зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1067455 - Reduce Fence::merge() call on compositor thread r=nical
This commit is contained in:
Родитель
464da0f9c2
Коммит
bae6e432e4
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче