Bug 1001417 - Forward fence objects in SharedSurfaceGralloc to Compositor r=jgilbert,nical

This commit is contained in:
Sotaro Ikeda 2014-06-08 06:18:53 -07:00
parent cf0a27ccbf
commit 539d95f87e
29 changed files with 465 additions and 31 deletions

View File

@ -333,6 +333,24 @@ GLLibraryEGL::EnsureInitialized()
MarkExtensionUnsupported(KHR_image_pixmap);
}
if (IsExtensionSupported(ANDROID_native_fence_sync)) {
GLLibraryLoader::SymLoadStruct nativeFenceSymbols[] = {
{ (PRFuncPtr*) &mSymbols.fDupNativeFenceFDANDROID, { "eglDupNativeFenceFDANDROID", nullptr } },
{ nullptr, { nullptr } }
};
bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
&nativeFenceSymbols[0],
lookupFunction);
if (!success) {
NS_ERROR("EGL supports ANDROID_native_fence_sync without exposing its functions!");
MarkExtensionUnsupported(ANDROID_native_fence_sync);
mSymbols.fDupNativeFenceFDANDROID = nullptr;
}
}
mInitialized = true;
reporter.SetSuccessful();
return true;

View File

@ -412,6 +412,14 @@ public:
return b;
}
EGLint fDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync)
{
MOZ_ASSERT(mSymbols.fDupNativeFenceFDANDROID);
BEFORE_GL_CALL;
EGLint ret = mSymbols.fDupNativeFenceFDANDROID(dpy, sync);
AFTER_GL_CALL;
return ret;
}
EGLDisplay Display() {
return mEGLDisplay;
@ -522,6 +530,8 @@ public:
pfnClientWaitSync fClientWaitSync;
typedef EGLBoolean (GLAPIENTRY * pfnGetSyncAttrib)(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *value);
pfnGetSyncAttrib fGetSyncAttrib;
typedef EGLint (GLAPIENTRY * pfnDupNativeFenceFDANDROID)(EGLDisplay dpy, EGLSync sync);
pfnDupNativeFenceFDANDROID fDupNativeFenceFDANDROID;
} mSymbols;
#ifdef DEBUG

View File

@ -153,11 +153,24 @@ SharedSurface_Gralloc::Fence()
// Android native fences are also likely to perform better.
if (mEGL->IsExtensionSupported(GLLibraryEGL::ANDROID_native_fence_sync)) {
mGL->MakeCurrent();
mSync = mEGL->fCreateSync(mEGL->Display(),
LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID,
nullptr);
if (mSync) {
EGLSync sync = mEGL->fCreateSync(mEGL->Display(),
LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID,
nullptr);
if (sync) {
mGL->fFlush();
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
int fenceFd = mEGL->fDupNativeFenceFDANDROID(mEGL->Display(), sync);
if (fenceFd != -1) {
mEGL->fDestroySync(mEGL->Display(), sync);
android::sp<android::Fence> fence(new android::Fence(fenceFd));
FenceHandle handle = FenceHandle(fence);
mTextureClient->SetAcquireFenceHandle(handle);
} else {
mSync = sync;
}
#else
mSync = sync;
#endif
return;
}
}

View File

@ -171,7 +171,7 @@ CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
}
if (grallocTextureClient->GetIPDLActor()) {
GetForwarder()->UseTexture(this, grallocTextureClient);
UseTexture(grallocTextureClient);
}
if (mBuffer && CompositorChild::ChildProcessHasCompositor()) {

View File

@ -202,6 +202,24 @@ CompositableClient::OnTransaction()
{
}
void
CompositableClient::UseTexture(TextureClient* aTexture)
{
MOZ_ASSERT(aTexture);
if (!aTexture) {
return;
}
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
FenceHandle handle = aTexture->GetAcquireFenceHandle();
if (handle.IsValid()) {
RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(handle);
mForwarder->SendFenceHandle(tracker, aTexture->GetIPDLActor(), handle);
}
#endif
mForwarder->UseTexture(this, aTexture);
}
void
CompositableClient::RemoveTexture(TextureClient* aTexture)
{

View File

@ -189,6 +189,8 @@ public:
*/
virtual void ClearCachedResources() {}
virtual void UseTexture(TextureClient* aTexture);
/**
* Should be called when deataching a TextureClient from a Compositable, because
* some platforms need to do some extra book keeping when this happens (for

View File

@ -291,13 +291,26 @@ public:
*/
void ForceRemove();
virtual void SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle) {}
virtual void SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle)
{
mReleaseFenceHandle = aReleaseFenceHandle;
}
const FenceHandle& GetReleaseFenceHandle() const
{
return mReleaseFenceHandle;
}
virtual void SetAcquireFenceHandle(FenceHandle aAcquireFenceHandle)
{
mAcquireFenceHandle = aAcquireFenceHandle;
}
const FenceHandle& GetAcquireFenceHandle() const
{
return mAcquireFenceHandle;
}
/**
* Set AsyncTransactionTracker of RemoveTextureFromCompositableAsync() transaction.
*/
@ -347,6 +360,7 @@ protected:
bool mShared;
bool mValid;
FenceHandle mReleaseFenceHandle;
FenceHandle mAcquireFenceHandle;
friend class TextureChild;
friend void TestTextureClientSurface(TextureClient*, gfxImageSurface*);

15
gfx/layers/ipc/AsyncTransactionTracker.cpp Normal file → Executable file
View File

@ -89,9 +89,13 @@ AsyncTransactionTrackersHolder::~AsyncTransactionTrackersHolder()
}
{
MOZ_ASSERT(sHolderLock);
MutexAutoLock lock(*sHolderLock);
if (sHolderLock) {
sHolderLock->Lock();
}
sTrackersHolders.erase(mSerial);
if (sHolderLock) {
sHolderLock->Unlock();
}
}
MOZ_COUNT_DTOR(AsyncTransactionTrackersHolder);
}
@ -170,13 +174,18 @@ AsyncTransactionTrackersHolder::SetReleaseFenceHandle(FenceHandle& aReleaseFence
void
AsyncTransactionTrackersHolder::ClearAllAsyncTransactionTrackers()
{
MutexAutoLock lock(*sHolderLock);
if (sHolderLock) {
sHolderLock->Lock();
}
std::map<uint64_t, RefPtr<AsyncTransactionTracker> >::iterator it;
for (it = mAsyncTransactionTrackeres.begin();
it != mAsyncTransactionTrackeres.end(); it++) {
it->second->NotifyCancel();
}
mAsyncTransactionTrackeres.clear();
if (sHolderLock) {
sHolderLock->Unlock();
}
}
void

View File

@ -184,6 +184,11 @@ public:
TextureClient* aTexture,
nsIntRegion* aRegion) = 0;
virtual void SendFenceHandle(AsyncTransactionTracker* aTracker,
PTextureChild* aTexture,
const FenceHandle& aFence) = 0;
void IdentifyTextureHost(const TextureFactoryIdentifier& aIdentifier);
virtual int32_t GetMaxTextureSize() const MOZ_OVERRIDE

View File

@ -18,10 +18,24 @@
#else
namespace mozilla {
namespace layers {
struct FenceHandleFromChild;
struct FenceHandle {
FenceHandle() {}
FenceHandle(const FenceHandleFromChild& aFenceHandle) {}
bool operator==(const FenceHandle&) const { return false; }
bool IsValid() const { return false; }
};
struct FenceHandleFromChild {
FenceHandleFromChild() {}
FenceHandleFromChild(const FenceHandle& aFence) {}
bool operator==(const FenceHandle&) const { return false; }
bool operator==(const FenceHandleFromChild&) const { return false; }
bool IsValid() const { return false; }
};
} // namespace layers
} // namespace mozilla
#endif // MOZ_WIDGET_GONK && ANDROID_VERSION >= 17
@ -36,6 +50,13 @@ struct ParamTraits<mozilla::layers::FenceHandle> {
static void Write(Message*, const paramType&) {}
static bool Read(const Message*, void**, paramType*) { return false; }
};
template <>
struct ParamTraits<mozilla::layers::FenceHandleFromChild> {
typedef mozilla::layers::FenceHandleFromChild paramType;
static void Write(Message*, const paramType&) {}
static bool Read(const Message*, void**, paramType*) { return false; }
};
#endif // MOZ_WIDGET_GONK && ANDROID_VERSION >= 17
} // namespace IPC

View File

@ -109,6 +109,100 @@ ParamTraits<FenceHandle>::Read(const Message* aMsg,
return false;
}
void
ParamTraits<FenceHandleFromChild>::Write(Message* aMsg,
const paramType& aParam)
{
#if ANDROID_VERSION >= 19
sp<Fence> flattenable = aParam.mFence;
#else
Flattenable *flattenable = aParam.mFence.get();
#endif
size_t nbytes = flattenable->getFlattenedSize();
size_t nfds = flattenable->getFdCount();
char data[nbytes];
int fds[nfds];
#if ANDROID_VERSION >= 19
// Make a copy of "data" and "fds" for flatten() to avoid casting problem
void *pdata = (void *)data;
int *pfds = fds;
flattenable->flatten(pdata, nbytes, pfds, nfds);
// In Kitkat, flatten() will change the value of nbytes and nfds, which dues
// to multiple parcelable object consumption. The actual size and fd count
// which returned by getFlattenedSize() and getFdCount() are not changed.
// So we change nbytes and nfds back by call corresponding calls.
nbytes = flattenable->getFlattenedSize();
nfds = flattenable->getFdCount();
#else
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
// the right thing and dup's the fd. If it's shared cross-thread,
// SCM_RIGHTS doesn't dup the fd. That's surprising, but we just
// deal with it here. NB: only the "default" (master) process can
// alloc gralloc buffers.
bool sameProcess = (XRE_GetProcessType() == GeckoProcessType_Default);
int dupFd = sameProcess ? dup(fds[n]) : fds[n];
//int dupFd = fds[n];
// These buffers can't die in transit because they're created
// synchonously and the parent-side buffer can only be dropped if
// there's a crash.
aMsg->WriteFileDescriptor(FileDescriptor(dupFd, false));
}
}
bool
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;
}
int fds[nfds];
for (size_t n = 0; n < nfds; ++n) {
FileDescriptor fd;
if (!aMsg->ReadFileDescriptor(aIter, &fd)) {
return false;
}
fds[n] = fd.fd;
}
sp<Fence> buffer(new Fence());
#if ANDROID_VERSION >= 19
// Make a copy of "data" and "fds" for unflatten() to avoid casting problem
void const *pdata = (void const *)data;
int const *pfds = fds;
if (NO_ERROR == buffer->unflatten(pdata, nbytes, pfds, nfds)) {
#else
Flattenable *flattenable = buffer.get();
if (NO_ERROR == flattenable->unflatten(data, nbytes, fds, nfds)) {
#endif
aResult->mFence = buffer;
return true;
}
return false;
}
} // namespace IPC
namespace mozilla {
@ -119,5 +213,14 @@ FenceHandle::FenceHandle(const sp<Fence>& aFence)
{
}
FenceHandle::FenceHandle(const FenceHandleFromChild& aFenceHandle) {
mFence = aFenceHandle.mFence;
}
FenceHandleFromChild::FenceHandleFromChild(const sp<Fence>& aFence)
: mFence(aFence)
{
}
} // namespace layers
} // namespace mozilla

View File

@ -16,6 +16,8 @@
namespace mozilla {
namespace layers {
struct FenceHandleFromChild;
struct FenceHandle {
typedef android::Fence Fence;
@ -23,6 +25,8 @@ struct FenceHandle {
{ }
FenceHandle(const android::sp<Fence>& aFence);
FenceHandle(const FenceHandleFromChild& aFenceHandle);
bool operator==(const FenceHandle& aOther) const {
return mFence.get() == aOther.mFence.get();
}
@ -35,6 +39,33 @@ struct FenceHandle {
android::sp<Fence> mFence;
};
struct FenceHandleFromChild {
typedef android::Fence Fence;
FenceHandleFromChild()
{ }
FenceHandleFromChild(const android::sp<Fence>& aFence);
FenceHandleFromChild(const FenceHandle& aFence) {
mFence = aFence.mFence;
}
bool operator==(const FenceHandle& aOther) const {
return mFence.get() == aOther.mFence.get();
}
bool operator==(const FenceHandleFromChild& aOther) const {
return mFence.get() == aOther.mFence.get();
}
bool IsValid() const
{
return mFence.get() && mFence->isValid();
}
android::sp<Fence> mFence;
};
} // namespace layers
} // namespace mozilla
@ -48,6 +79,14 @@ struct ParamTraits<mozilla::layers::FenceHandle> {
static bool Read(const Message* aMsg, void** aIter, paramType* aResult);
};
template <>
struct ParamTraits<mozilla::layers::FenceHandleFromChild> {
typedef mozilla::layers::FenceHandleFromChild paramType;
static void Write(Message* aMsg, const paramType& aParam);
static bool Read(const Message* aMsg, void** aIter, paramType* aResult);
};
} // namespace IPC
#endif // mozilla_layers_FenceUtilsGonk_h

View File

@ -151,6 +151,19 @@ ImageBridgeChild::UpdatedTexture(CompositableClient* aCompositable,
region));
}
void
ImageBridgeChild::SendFenceHandle(AsyncTransactionTracker* aTracker,
PTextureChild* aTexture,
const FenceHandle& aFence)
{
HoldUntilComplete(aTracker);
InfallibleTArray<AsyncChildMessageData> messages;
messages.AppendElement(OpDeliverFenceFromChild(aTracker->GetId(),
nullptr, aTexture,
FenceHandleFromChild(aFence)));
SendChildAsyncMessages(messages);
}
void
ImageBridgeChild::UpdatePictureRect(CompositableClient* aCompositable,
const nsIntRect& aRect)
@ -533,6 +546,8 @@ ImageBridgeChild::StartUpInChildProcess(Transport* aTransport,
{
NS_ASSERTION(NS_IsMainThread(), "Should be on the main Thread!");
gfxPlatform::GetPlatform();
ProcessHandle processHandle;
if (!base::OpenProcessHandle(aOtherProcess, &processHandle)) {
return nullptr;
@ -802,7 +817,7 @@ ImageBridgeChild::DeallocPTextureChild(PTextureChild* actor)
}
bool
ImageBridgeChild::RecvParentAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessages)
ImageBridgeChild::RecvParentAsyncMessages(const InfallibleTArray<AsyncParentMessageData>& aMessages)
{
for (AsyncParentMessageArray::index_type i = 0; i < aMessages.Length(); ++i) {
const AsyncParentMessageData& message = aMessages[i];
@ -833,13 +848,18 @@ ImageBridgeChild::RecvParentAsyncMessage(const InfallibleTArray<AsyncParentMessa
SendChildAsyncMessages(replies);
break;
}
case AsyncParentMessageData::TOpReplyDeliverFence: {
const OpReplyDeliverFence& op = message.get_OpReplyDeliverFence();
TransactionCompleteted(op.transactionId());
break;
}
case AsyncParentMessageData::TOpReplyRemoveTexture: {
const OpReplyRemoveTexture& op = message.get_OpReplyRemoveTexture();
AsyncTransactionTrackersHolder::TransactionCompleteted(op.holderId(),
op.transactionId());
break;
}
break;
}
default:
NS_ERROR("unknown AsyncParentMessageData type");
return false;

View File

@ -11,6 +11,7 @@
#include "mozilla/Attributes.h" // for MOZ_OVERRIDE
#include "mozilla/RefPtr.h" // for TemporaryRef
#include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc
#include "mozilla/layers/AsyncTransactionTracker.h" // for AsyncTransactionTrackerHolder
#include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/layers/CompositorTypes.h" // for TextureIdentifier, etc
#include "mozilla/layers/PImageBridgeChild.h"
@ -101,6 +102,7 @@ bool InImageBridgeChildThread();
*/
class ImageBridgeChild : public PImageBridgeChild
, public CompositableForwarder
, public AsyncTransactionTrackersHolder
{
friend class ImageContainer;
typedef InfallibleTArray<AsyncParentMessageData> AsyncParentMessageArray;
@ -186,7 +188,7 @@ public:
DeallocPTextureChild(PTextureChild* actor) MOZ_OVERRIDE;
virtual bool
RecvParentAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessages) MOZ_OVERRIDE;
RecvParentAsyncMessages(const InfallibleTArray<AsyncParentMessageData>& aMessages) MOZ_OVERRIDE;
TemporaryRef<ImageClient> CreateImageClient(CompositableType aType);
TemporaryRef<ImageClient> CreateImageClientNow(CompositableType aType);
@ -222,6 +224,10 @@ public:
TextureClient* aClientOnBlack,
TextureClient* aClientOnWhite) MOZ_OVERRIDE;
virtual void SendFenceHandle(AsyncTransactionTracker* aTracker,
PTextureChild* aTexture,
const FenceHandle& aFence) MOZ_OVERRIDE;
virtual void RemoveTextureFromCompositable(CompositableClient* aCompositable,
TextureClient* aTexture) MOZ_OVERRIDE;

View File

@ -23,6 +23,7 @@
#include "mozilla/layers/LayersSurfaces.h" // for PGrallocBufferParent
#include "mozilla/layers/PCompositableParent.h"
#include "mozilla/layers/PImageBridgeParent.h"
#include "mozilla/layers/TextureHostOGL.h" // for TextureHostOGL
#include "mozilla/layers/Compositor.h"
#include "mozilla/mozalloc.h" // for operator new, etc
#include "mozilla/unused.h"
@ -208,13 +209,13 @@ ImageBridgeParent::SendFenceHandle(AsyncTransactionTracker* aTracker,
messages.AppendElement(OpDeliverFence(aTracker->GetId(),
aTexture, nullptr,
aFence));
mozilla::unused << SendParentAsyncMessage(messages);
mozilla::unused << SendParentAsyncMessages(messages);
}
void
ImageBridgeParent::SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage)
{
mozilla::unused << SendParentAsyncMessage(aMessage);
mozilla::unused << SendParentAsyncMessages(aMessage);
}
bool
@ -224,6 +225,27 @@ ImageBridgeParent::RecvChildAsyncMessages(const InfallibleTArray<AsyncChildMessa
const AsyncChildMessageData& message = aMessages[i];
switch (message.type()) {
case AsyncChildMessageData::TOpDeliverFenceFromChild: {
const OpDeliverFenceFromChild& op = message.get_OpDeliverFenceFromChild();
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
FenceHandle fence = FenceHandle(op.fence());
PTextureParent* parent = op.textureParent();
TextureHostOGL* hostOGL = nullptr;
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(parent);
if (texture) {
hostOGL = texture->AsHostOGL();
}
if (hostOGL) {
hostOGL->SetAcquireFence(fence.mFence);
}
#endif
// Send back a response.
InfallibleTArray<AsyncParentMessageData> replies;
replies.AppendElement(OpReplyDeliverFence(op.transactionId()));
mozilla::unused << SendParentAsyncMessages(replies);
break;
}
case AsyncChildMessageData::TOpReplyDeliverFence: {
const OpReplyDeliverFence& op = message.get_OpReplyDeliverFence();
TransactionCompleteted(op.transactionId());
@ -304,7 +326,7 @@ ImageBridgeParent::ReplyRemoveTexture(const OpReplyRemoveTexture& aReply)
{
InfallibleTArray<AsyncParentMessageData> messages;
messages.AppendElement(aReply);
mozilla::unused << SendParentAsyncMessage(messages);
mozilla::unused << SendParentAsyncMessages(messages);
}
/*static*/ void
@ -339,7 +361,7 @@ ImageBridgeParent::SendFenceHandleToTrackerIfPresent(uint64_t aDestHolderId,
aDestHolderId,
aTransactionId,
fence));
mozilla::unused << SendParentAsyncMessage(messages);
mozilla::unused << SendParentAsyncMessages(messages);
}
/*static*/ void

View File

@ -66,7 +66,7 @@ LayerTransactionChild::DeallocPCompositableChild(PCompositableChild* actor)
}
bool
LayerTransactionChild::RecvParentAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessages)
LayerTransactionChild::RecvParentAsyncMessages(const InfallibleTArray<AsyncParentMessageData>& aMessages)
{
for (AsyncParentMessageArray::index_type i = 0; i < aMessages.Length(); ++i) {
const AsyncParentMessageData& message = aMessages[i];
@ -91,6 +91,11 @@ LayerTransactionChild::RecvParentAsyncMessage(const InfallibleTArray<AsyncParent
}
break;
}
case AsyncParentMessageData::TOpReplyDeliverFence: {
const OpReplyDeliverFence& op = message.get_OpReplyDeliverFence();
TransactionCompleteted(op.transactionId());
break;
}
default:
NS_ERROR("unknown AsyncParentMessageData type");
return false;
@ -99,9 +104,23 @@ LayerTransactionChild::RecvParentAsyncMessage(const InfallibleTArray<AsyncParent
return true;
}
void
LayerTransactionChild::SendFenceHandle(AsyncTransactionTracker* aTracker,
PTextureChild* aTexture,
const FenceHandle& aFence)
{
HoldUntilComplete(aTracker);
InfallibleTArray<AsyncChildMessageData> messages;
messages.AppendElement(OpDeliverFenceFromChild(aTracker->GetId(),
nullptr, aTexture,
FenceHandleFromChild(aFence)));
SendChildAsyncMessages(messages);
}
void
LayerTransactionChild::ActorDestroy(ActorDestroyReason why)
{
DestroyAsyncTransactionTrackersHolder();
#ifdef MOZ_B2G
// Due to poor lifetime management of gralloc (and possibly shmems) we will
// crash at some point in the future when we get destroyed due to abnormal

View File

@ -11,6 +11,7 @@
#include <stdint.h> // for uint32_t
#include "mozilla/Attributes.h" // for MOZ_OVERRIDE
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/layers/AsyncTransactionTracker.h" // for AsyncTransactionTracker
#include "mozilla/layers/PLayerTransactionChild.h"
#include "mozilla/RefPtr.h"
@ -24,6 +25,7 @@ class ShadowLayerForwarder;
namespace layers {
class LayerTransactionChild : public PLayerTransactionChild
, public AsyncTransactionTrackersHolder
{
typedef InfallibleTArray<AsyncParentMessageData> AsyncParentMessageArray;
public:
@ -47,6 +49,10 @@ public:
mForwarder = aForwarder;
}
virtual void SendFenceHandle(AsyncTransactionTracker* aTracker,
PTextureChild* aTexture,
const FenceHandle& aFence);
protected:
LayerTransactionChild()
: mForwarder(nullptr)
@ -67,7 +73,7 @@ protected:
virtual bool DeallocPTextureChild(PTextureChild* actor) MOZ_OVERRIDE;
virtual bool
RecvParentAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessages) MOZ_OVERRIDE;
RecvParentAsyncMessages(const InfallibleTArray<AsyncParentMessageData>& aMessages) MOZ_OVERRIDE;
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;

View File

@ -27,6 +27,7 @@
#include "mozilla/layers/LayersTypes.h" // for MOZ_LAYERS_LOG
#include "mozilla/layers/PCompositableParent.h"
#include "mozilla/layers/PLayerParent.h" // for PLayerParent
#include "mozilla/layers/TextureHostOGL.h" // for TextureHostOGL
#include "mozilla/layers/ThebesLayerComposite.h"
#include "mozilla/mozalloc.h" // for operator delete, etc
#include "mozilla/unused.h"
@ -802,6 +803,27 @@ LayerTransactionParent::RecvChildAsyncMessages(const InfallibleTArray<AsyncChild
const AsyncChildMessageData& message = aMessages[i];
switch (message.type()) {
case AsyncChildMessageData::TOpDeliverFenceFromChild: {
const OpDeliverFenceFromChild& op = message.get_OpDeliverFenceFromChild();
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
FenceHandle fence = FenceHandle(op.fence());
PTextureParent* parent = op.textureParent();
TextureHostOGL* hostOGL = nullptr;
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(parent);
if (texture) {
hostOGL = texture->AsHostOGL();
}
if (hostOGL) {
hostOGL->SetAcquireFence(fence.mFence);
}
#endif
// Send back a response.
InfallibleTArray<AsyncParentMessageData> replies;
replies.AppendElement(OpReplyDeliverFence(op.transactionId()));
mozilla::unused << SendParentAsyncMessages(replies);
break;
}
case AsyncChildMessageData::TOpReplyDeliverFence: {
const OpReplyDeliverFence& op = message.get_OpReplyDeliverFence();
TransactionCompleteted(op.transactionId());
@ -836,13 +858,13 @@ LayerTransactionParent::SendFenceHandle(AsyncTransactionTracker* aTracker,
messages.AppendElement(OpDeliverFence(aTracker->GetId(),
aTexture, nullptr,
aFence));
mozilla::unused << SendParentAsyncMessage(messages);
mozilla::unused << SendParentAsyncMessages(messages);
}
void
LayerTransactionParent::SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage)
{
mozilla::unused << SendParentAsyncMessage(aMessage);
mozilla::unused << SendParentAsyncMessages(aMessage);
}
} // namespace layers

View File

@ -40,6 +40,7 @@ using mozilla::layers::DiagnosticTypes from "mozilla/layers/CompositorTypes.h";
using struct mozilla::layers::FrameMetrics from "FrameMetrics.h";
using mozilla::layers::FrameMetrics::ViewID from "FrameMetrics.h";
using struct mozilla::layers::FenceHandle from "mozilla/layers/FenceUtils.h";
using struct mozilla::layers::FenceHandleFromChild from "mozilla/layers/FenceUtils.h";
using mozilla::layers::TextureIdentifier from "mozilla/layers/CompositorTypes.h";
namespace mozilla {
@ -387,6 +388,12 @@ struct OpDeliverFenceToTracker {
FenceHandle fence;
};
struct OpDeliverFenceFromChild {
uint64_t transactionId;
PTexture texture;
FenceHandleFromChild fence;
};
struct OpReplyDeliverFence {
uint64_t transactionId;
};
@ -466,10 +473,12 @@ union EditReply {
union AsyncParentMessageData {
OpDeliverFence;
OpDeliverFenceToTracker;
OpReplyDeliverFence;
OpReplyRemoveTexture;
};
union AsyncChildMessageData {
OpDeliverFenceFromChild;
OpReplyDeliverFence;
};

View File

@ -29,7 +29,7 @@ intr protocol PImageBridge
manages PTexture;
child:
async ParentAsyncMessage(AsyncParentMessageData[] aMessages);
async ParentAsyncMessages(AsyncParentMessageData[] aMessages);
parent:

View File

@ -43,7 +43,7 @@ sync protocol PLayerTransaction {
manages PTexture;
child:
async ParentAsyncMessage(AsyncParentMessageData[] aMessages);
async ParentAsyncMessages(AsyncParentMessageData[] aMessages);
parent:
async PLayer();

View File

@ -410,6 +410,17 @@ ShadowLayerForwarder::UseComponentAlphaTextures(CompositableClient* aCompositabl
nullptr, aTextureOnWhite->GetIPDLActor()));
}
void
ShadowLayerForwarder::SendFenceHandle(AsyncTransactionTracker* aTracker,
PTextureChild* aTexture,
const FenceHandle& aFence)
{
if (!HasShadowManager() || !mShadowManager->IPCOpen()) {
return;
}
mShadowManager->SendFenceHandle(aTracker, aTexture, aFence);
}
void
ShadowLayerForwarder::RemoveTextureFromCompositable(CompositableClient* aCompositable,
TextureClient* aTexture)

View File

@ -288,6 +288,10 @@ public:
TextureClient* aClientOnBlack,
TextureClient* aClientOnWhite) MOZ_OVERRIDE;
virtual void SendFenceHandle(AsyncTransactionTracker* aTracker,
PTextureChild* aTexture,
const FenceHandle& aFence) MOZ_OVERRIDE;
/**
* End the current transaction and forward it to LayerManagerComposite.
* |aReplies| are directions from the LayerManagerComposite to the

View File

@ -75,12 +75,6 @@ GrallocTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
return true;
}
void
GrallocTextureClientOGL::SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle)
{
mReleaseFenceHandle = aReleaseFenceHandle;
}
void
GrallocTextureClientOGL::SetRemoveFromCompositableTracker(AsyncTransactionTracker* aTracker)
{

View File

@ -60,8 +60,6 @@ public:
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE;
virtual void SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle) MOZ_OVERRIDE;
virtual void SetRemoveFromCompositableTracker(AsyncTransactionTracker* aTracker) MOZ_OVERRIDE;
virtual void WaitForBufferOwnership() MOZ_OVERRIDE;

View File

@ -90,9 +90,11 @@ TextureTargetForAndroidPixelFormat(android::PixelFormat aFormat)
}
GrallocTextureSourceOGL::GrallocTextureSourceOGL(CompositorOGL* aCompositor,
GrallocTextureHostOGL* aTextureHost,
android::GraphicBuffer* aGraphicBuffer,
gfx::SurfaceFormat aFormat)
: mCompositor(aCompositor)
, mTextureHost(aTextureHost)
, mGraphicBuffer(aGraphicBuffer)
, mEGLImage(0)
, mFormat(aFormat)
@ -300,6 +302,7 @@ GrallocTextureHostOGL::GrallocTextureHostOGL(TextureFlags aFlags,
NS_WARNING("gralloc buffer is nullptr");
}
mTextureSource = new GrallocTextureSourceOGL(nullptr,
this,
graphicBuffer,
format);
}
@ -440,6 +443,12 @@ GrallocTextureSourceOGL::GetGLTexture()
void
GrallocTextureSourceOGL::BindEGLImage()
{
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
if (mTextureHost) {
mTextureHost->WaitAcquireFenceSyncComplete();
}
#endif
if (mCompositableBackendData) {
CompositableDataGonkOGL* backend = static_cast<CompositableDataGonkOGL*>(mCompositableBackendData.get());
backend->BindEGLImage(GetTextureTarget(), mEGLImage);

View File

@ -23,6 +23,7 @@ public:
friend class GrallocTextureHostOGL;
GrallocTextureSourceOGL(CompositorOGL* aCompositor,
GrallocTextureHostOGL* aTextureHost,
android::GraphicBuffer* aGraphicBuffer,
gfx::SurfaceFormat aFormat);
@ -56,6 +57,7 @@ public:
void ForgetBuffer()
{
mGraphicBuffer = nullptr;
mTextureHost = nullptr;
}
TemporaryRef<gfx::DataSourceSurface> GetAsSurface();
@ -68,6 +70,7 @@ public:
protected:
CompositorOGL* mCompositor;
GrallocTextureHostOGL* mTextureHost;
android::sp<android::GraphicBuffer> mGraphicBuffer;
EGLImage mEGLImage;
GLuint mTexture;

View File

@ -5,6 +5,7 @@
#include "TextureHostOGL.h"
#include "GLContext.h" // for GLContext, etc
#include "GLLibraryEGL.h" // for GLLibraryEGL
#include "GLSharedHandleHelpers.h"
#include "GLUploadHelpers.h"
#include "GLReadTexImageHelper.h"
@ -220,6 +221,56 @@ TextureHostOGL::GetAndResetReleaseFence()
mReleaseFence = android::Fence::NO_FENCE;
return mPrevReleaseFence;
}
void
TextureHostOGL::SetAcquireFence(const android::sp<android::Fence>& aAcquireFence)
{
mAcquireFence = aAcquireFence;
}
android::sp<android::Fence>
TextureHostOGL::GetAcquireFence()
{
return mAcquireFence;
}
void
TextureHostOGL::WaitAcquireFenceSyncComplete()
{
if (!mAcquireFence.get() || !mAcquireFence->isValid()) {
return;
}
int fenceFd = mAcquireFence->dup();
if (fenceFd == -1) {
NS_WARNING("failed to dup fence fd");
return;
}
EGLint attribs[] = {
LOCAL_EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd,
LOCAL_EGL_NONE
};
EGLSync sync = sEGLLibrary.fCreateSync(EGL_DISPLAY(),
LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID,
attribs);
if (!sync) {
NS_WARNING("failed to create native fence sync");
return;
}
EGLint status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(),
sync,
0,
LOCAL_EGL_FOREVER);
if (status != LOCAL_EGL_CONDITION_SATISFIED) {
NS_WARNING("failed to wait native fence sync");
}
MOZ_ALWAYS_TRUE( sEGLLibrary.fDestroySync(EGL_DISPLAY(), sync) );
mAcquireFence = nullptr;
}
#endif
bool

View File

@ -172,9 +172,17 @@ public:
*/
virtual android::sp<android::Fence> GetAndResetReleaseFence();
virtual void SetAcquireFence(const android::sp<android::Fence>& aAcquireFence);
virtual android::sp<android::Fence> GetAcquireFence();
virtual void WaitAcquireFenceSyncComplete();
protected:
android::sp<android::Fence> mReleaseFence;
android::sp<android::Fence> mAcquireFence;
/**
* Hold previous ReleaseFence to prevent Fence delivery failure via gecko IPC.
* Fence is a kernel object and its lifetime is managed by a reference count.