mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Bug 1001417 - Forward fence objects in SharedSurfaceGralloc to Compositor r=jgilbert,nical
This commit is contained in:
parent
cf0a27ccbf
commit
539d95f87e
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||
}
|
||||
|
||||
if (grallocTextureClient->GetIPDLActor()) {
|
||||
GetForwarder()->UseTexture(this, grallocTextureClient);
|
||||
UseTexture(grallocTextureClient);
|
||||
}
|
||||
|
||||
if (mBuffer && CompositorChild::ChildProcessHasCompositor()) {
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
15
gfx/layers/ipc/AsyncTransactionTracker.cpp
Normal file → Executable 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -29,7 +29,7 @@ intr protocol PImageBridge
|
||||
manages PTexture;
|
||||
|
||||
child:
|
||||
async ParentAsyncMessage(AsyncParentMessageData[] aMessages);
|
||||
async ParentAsyncMessages(AsyncParentMessageData[] aMessages);
|
||||
|
||||
parent:
|
||||
|
||||
|
@ -43,7 +43,7 @@ sync protocol PLayerTransaction {
|
||||
manages PTexture;
|
||||
|
||||
child:
|
||||
async ParentAsyncMessage(AsyncParentMessageData[] aMessages);
|
||||
async ParentAsyncMessages(AsyncParentMessageData[] aMessages);
|
||||
|
||||
parent:
|
||||
async PLayer();
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -75,12 +75,6 @@ GrallocTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureClientOGL::SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle)
|
||||
{
|
||||
mReleaseFenceHandle = aReleaseFenceHandle;
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureClientOGL::SetRemoveFromCompositableTracker(AsyncTransactionTracker* aTracker)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user