Bug 1006957 - Handle buffer ownership between SurfaceStream and CanvasClient r=nical

This commit is contained in:
Sotaro Ikeda 2014-05-23 17:52:43 -07:00
parent 1807413f5e
commit e66ebd661d
33 changed files with 534 additions and 322 deletions

View File

@ -210,7 +210,7 @@ SharedSurface_Gralloc::WaitSync()
void
SharedSurface_Gralloc::WaitForBufferOwnership()
{
mTextureClient->WaitReleaseFence();
mTextureClient->WaitForBufferOwnership();
}
}

View File

@ -5,6 +5,7 @@
#include "mozilla/layers/CanvasClient.h"
#include "ClientCanvasLayer.h" // for ClientCanvasLayer
#include "CompositorChild.h" // for CompositorChild
#include "GLContext.h" // for GLContext
#include "GLScreenBuffer.h" // for GLScreenBuffer
#include "SurfaceStream.h" // for SurfaceStream
@ -172,6 +173,17 @@ CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
if (grallocTextureClient->GetIPDLActor()) {
GetForwarder()->UseTexture(this, grallocTextureClient);
}
if (mBuffer && CompositorChild::ChildProcessHasCompositor()) {
// remove old buffer from CompositableHost
RefPtr<AsyncTransactionTracker> tracker = new RemoveTextureFromCompositableTracker(this);
// Hold TextureClient until transaction complete.
tracker->SetTextureClient(mBuffer);
mBuffer->SetRemoveFromCompositableTracker(tracker);
// RemoveTextureFromCompositableAsync() expects CompositorChild's presence.
GetForwarder()->RemoveTextureFromCompositableAsync(tracker, this, mBuffer);
}
mBuffer = grallocTextureClient;
#else
printf_stderr("isCrossProcess, but not MOZ_WIDGET_GONK! Someone needs to write some code!");
MOZ_ASSERT(false);

View File

@ -6,7 +6,6 @@
#include "mozilla/layers/CompositableClient.h"
#include <stdint.h> // for uint64_t, uint32_t
#include "gfxPlatform.h" // for gfxPlatform
#include "mozilla/layers/AsyncTransactionTracker.h" // for AsyncTransactionTracker
#include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/layers/TextureClient.h" // for TextureClient, etc
#include "mozilla/layers/TextureClientOGL.h"
@ -70,6 +69,13 @@ CompositableClient::HoldUntilComplete(PCompositableChild* aActor, AsyncTransacti
child->HoldUntilComplete(aTracker);
}
/* static */ uint64_t
CompositableClient::GetTrackersHolderId(PCompositableChild* aActor)
{
CompositableChild* child = static_cast<CompositableChild*>(aActor);
return child->GetId();
}
/* static */ PCompositableChild*
CompositableClient::CreateIPDLActor()
{

View File

@ -12,22 +12,70 @@
#include "mozilla/Assertions.h" // for MOZ_CRASH
#include "mozilla/RefPtr.h" // for TemporaryRef, RefCounted
#include "mozilla/gfx/Types.h" // for SurfaceFormat
#include "mozilla/layers/AsyncTransactionTracker.h" // for AsyncTransactionTracker
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/LayersTypes.h" // for LayersBackend
#include "mozilla/layers/TextureClient.h" // for TextureClient
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
namespace mozilla {
namespace layers {
class AsyncTransactionTracker;
class CompositableClient;
class TextureClient;
class BufferTextureClient;
class ImageBridgeChild;
class CompositableForwarder;
class CompositableChild;
class SurfaceDescriptor;
class PCompositableChild;
/**
* Handle RemoveTextureFromCompositableAsync() transaction.
*/
class RemoveTextureFromCompositableTracker : public AsyncTransactionTracker {
public:
RemoveTextureFromCompositableTracker(CompositableClient* aCompositableClient)
: mCompositableClient(aCompositableClient)
{
MOZ_COUNT_CTOR(RemoveTextureFromCompositableTracker);
}
~RemoveTextureFromCompositableTracker()
{
MOZ_COUNT_DTOR(RemoveTextureFromCompositableTracker);
}
virtual void Complete() MOZ_OVERRIDE
{
// The TextureClient's recycling is postponed until the transaction
// complete.
mTextureClient = nullptr;
mCompositableClient = nullptr;
}
virtual void Cancel() MOZ_OVERRIDE
{
mTextureClient = nullptr;
mCompositableClient = nullptr;
}
virtual void SetTextureClient(TextureClient* aTextureClient) MOZ_OVERRIDE
{
mTextureClient = aTextureClient;
}
virtual void SetReleaseFenceHandle(FenceHandle& aReleaseFenceHandle) MOZ_OVERRIDE
{
if (mTextureClient) {
mTextureClient->SetReleaseFenceHandle(aReleaseFenceHandle);
}
}
private:
RefPtr<CompositableClient> mCompositableClient;
RefPtr<TextureClient> mTextureClient;
};
/**
* CompositableClient manages the texture-specific logic for composite layers,
* independently of the layer. It is the content side of a CompositableClient/
@ -174,6 +222,8 @@ public:
static void HoldUntilComplete(PCompositableChild* aActor, AsyncTransactionTracker* aTracker);
static uint64_t GetTrackersHolderId(PCompositableChild* aActor);
protected:
CompositableChild* mCompositableChild;
CompositableForwarder* mForwarder;

View File

@ -5,6 +5,7 @@
#include "mozilla/layers/ContentClient.h"
#include "BasicLayers.h" // for BasicLayerManager
#include "CompositorChild.h" // for CompositorChild
#include "gfxColor.h" // for gfxRGBA
#include "gfxContext.h" // for gfxContext, etc
#include "gfxPlatform.h" // for gfxPlatform
@ -356,6 +357,36 @@ ContentClientDoubleBuffered::DestroyFrontBuffer()
}
}
void
ContentClientDoubleBuffered::Updated(const nsIntRegion& aRegionToDraw,
const nsIntRegion& aVisibleRegion,
bool aDidSelfCopy)
{
ContentClientRemoteBuffer::Updated(aRegionToDraw, aVisibleRegion, aDidSelfCopy);
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
if (mFrontClient && CompositorChild::ChildProcessHasCompositor()) {
// remove old buffer from CompositableHost
RefPtr<AsyncTransactionTracker> tracker = new RemoveTextureFromCompositableTracker(this);
// Hold TextureClient until transaction complete.
tracker->SetTextureClient(mFrontClient);
mFrontClient->SetRemoveFromCompositableTracker(tracker);
// RemoveTextureFromCompositableAsync() expects CompositorChild's presence.
GetForwarder()->RemoveTextureFromCompositableAsync(tracker, this, mFrontClient);
}
if (mFrontClientOnWhite && CompositorChild::ChildProcessHasCompositor()) {
// remove old buffer from CompositableHost
RefPtr<AsyncTransactionTracker> tracker = new RemoveTextureFromCompositableTracker(this);
// Hold TextureClient until transaction complete.
tracker->SetTextureClient(mFrontClientOnWhite);
mFrontClientOnWhite->SetRemoveFromCompositableTracker(tracker);
// RemoveTextureFromCompositableAsync() expects CompositorChild's presence.
GetForwarder()->RemoveTextureFromCompositableAsync(tracker, this, mFrontClientOnWhite);
}
#endif
}
void
ContentClientDoubleBuffered::SwapBuffers(const nsIntRegion& aFrontUpdatedRegion)
{

View File

@ -331,6 +331,10 @@ public:
mFrontClientOnWhite = nullptr;
}
virtual void Updated(const nsIntRegion& aRegionToDraw,
const nsIntRegion& aVisibleRegion,
bool aDidSelfCopy) MOZ_OVERRIDE;
virtual void SwapBuffers(const nsIntRegion& aFrontUpdatedRegion) MOZ_OVERRIDE;
virtual void BeginPaint() MOZ_OVERRIDE;

View File

@ -41,46 +41,6 @@ namespace layers {
using namespace mozilla::gfx;
/**
* Handle RemoveTextureFromCompositableAsync() transaction.
*/
class RemoveTextureFromCompositableTracker : public AsyncTransactionTracker {
public:
RemoveTextureFromCompositableTracker(CompositableClient* aCompositableClient)
: mCompositableClient(aCompositableClient)
{
MOZ_COUNT_CTOR(RemoveTextureFromCompositableTracker);
}
~RemoveTextureFromCompositableTracker()
{
MOZ_COUNT_DTOR(RemoveTextureFromCompositableTracker);
}
virtual void Complete() MOZ_OVERRIDE
{
// The TextureClient's recycling is postponed until the transaction
// complete.
mTextureClient = nullptr;
mCompositableClient = nullptr;
}
virtual void Cancel() MOZ_OVERRIDE
{
mTextureClient = nullptr;
mCompositableClient = nullptr;
}
virtual void SetTextureClient(TextureClient* aTextureClient) MOZ_OVERRIDE
{
mTextureClient = aTextureClient;
}
private:
RefPtr<CompositableClient> mCompositableClient;
RefPtr<TextureClient> mTextureClient;
};
/* static */ TemporaryRef<ImageClient>
ImageClient::CreateImageClient(CompositableType aCompositableHostType,
CompositableForwarder* aForwarder,

View File

@ -64,7 +64,7 @@ SimpleTextureClientPool::GetTextureClient(bool aAutoRecycle)
RefPtr<TextureClient> textureClient;
if (mAvailableTextureClients.size()) {
textureClient = mAvailableTextureClients.top();
textureClient->WaitReleaseFence();
textureClient->WaitForBufferOwnership();
mAvailableTextureClients.pop();
RECYCLE_LOG("%s Skip allocate (%i left), returning %p\n", (mFormat == SurfaceFormat::B8G8R8A8?"poolA":"poolX"), mAvailableTextureClients.size(), textureClient.get());

View File

@ -33,6 +33,7 @@ class gfxImageSurface;
namespace mozilla {
namespace layers {
class AsyncTransactionTracker;
class ContentClient;
class CompositableForwarder;
class ISurfaceAllocator;
@ -298,11 +299,14 @@ public:
}
/**
* Wait until the current buffer is no longer being read.
*
* Platform support is necessary. gonk JB supports this function.
* Set AsyncTransactionTracker of RemoveTextureFromCompositableAsync() transaction.
*/
virtual void WaitReleaseFence() {}
virtual void SetRemoveFromCompositableTracker(AsyncTransactionTracker* aTracker) {}
/**
* This function waits until the buffer is no longer being used.
*/
virtual void WaitForBufferOwnership() {}
private:
/**

View File

@ -44,7 +44,7 @@ TextureClientPool::GetTextureClient()
RefPtr<TextureClient> textureClient;
if (mTextureClients.size()) {
textureClient = mTextureClients.top();
textureClient->WaitReleaseFence();
textureClient->WaitForBufferOwnership();
mTextureClients.pop();
return textureClient;
}

View File

@ -70,45 +70,8 @@ public:
}
virtual void SetCompositor(Compositor* aCompositor) {}
virtual void ClearData()
{
mCurrentReleaseFenceTexture = nullptr;
ClearPendingReleaseFenceTextureList();
}
virtual void ClearData() {}
/**
* Store a texture currently used for Composition.
* This function is called when the texutre might receive ReleaseFence
* as a result of Composition.
*/
void SetCurrentReleaseFenceTexture(TextureHost* aTexture)
{
if (mCurrentReleaseFenceTexture) {
mPendingReleaseFenceTextures.push_back(mCurrentReleaseFenceTexture);
}
mCurrentReleaseFenceTexture = aTexture;
}
virtual std::vector< RefPtr<TextureHost> >& GetPendingReleaseFenceTextureList()
{
return mPendingReleaseFenceTextures;
}
virtual void ClearPendingReleaseFenceTextureList()
{
return mPendingReleaseFenceTextures.clear();
}
protected:
/**
* Store a TextureHost currently used for Composition
* and it might receive ReleaseFence for the texutre.
*/
RefPtr<TextureHost> mCurrentReleaseFenceTexture;
/**
* Store TextureHosts that might have ReleaseFence to be delivered
* to TextureClient by CompositableHost.
*/
std::vector< RefPtr<TextureHost> > mPendingReleaseFenceTextures;
};
/**

View File

@ -128,6 +128,24 @@ TextureHost::SendFenceHandleIfPresent(PTextureParent* actor)
parent->SendFenceHandleIfPresent();
}
FenceHandle
TextureHost::GetAndResetReleaseFenceHandle()
{
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
TextureHostOGL* hostOGL = this->AsHostOGL();
if (!hostOGL) {
return FenceHandle();
}
android::sp<android::Fence> fence = hostOGL->GetAndResetReleaseFence();
if (fence.get() && fence->isValid()) {
FenceHandle handle = FenceHandle(fence);
return handle;
}
#endif
return FenceHandle();
}
// implemented in TextureHostOGL.cpp
TemporaryRef<TextureHost> CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
@ -663,7 +681,7 @@ TextureParent::SendFenceHandleIfPresent()
// In this case, HWC implicitly handles buffer's fence.
FenceHandle handle = FenceHandle(fence);
RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(fence);
RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(handle);
mCompositableManager->SendFenceHandle(tracker, this, handle);
}
}

View File

@ -16,6 +16,7 @@
#include "mozilla/gfx/Point.h" // for IntSize, IntPoint
#include "mozilla/gfx/Types.h" // for SurfaceFormat, etc
#include "mozilla/layers/CompositorTypes.h" // for TextureFlags, etc
#include "mozilla/layers/FenceUtils.h" // for FenceHandle
#include "mozilla/layers/LayersTypes.h" // for LayerRenderState, etc
#include "mozilla/mozalloc.h" // for operator delete
#include "nsCOMPtr.h" // for already_AddRefed
@ -418,6 +419,8 @@ public:
static void SendFenceHandleIfPresent(PTextureParent* actor);
FenceHandle GetAndResetReleaseFenceHandle();
/**
* Specific to B2G's Composer2D
* XXX - more doc here

View File

@ -65,10 +65,21 @@ AsyncTransactionTracker::NotifyCancel()
mCompletedMonitor.Notify();
}
uint64_t AsyncTransactionTrackersHolder::sSerialCounter(0);
Mutex* AsyncTransactionTrackersHolder::sHolderLock = nullptr;
std::map<uint64_t, AsyncTransactionTrackersHolder*> AsyncTransactionTrackersHolder::sTrackersHolders;
AsyncTransactionTrackersHolder::AsyncTransactionTrackersHolder()
: mIsTrackersHolderDestroyed(false)
: mSerial(GetNextSerial())
, mIsTrackersHolderDestroyed(false)
{
MOZ_COUNT_CTOR(AsyncTransactionTrackersHolder);
{
MOZ_ASSERT(sHolderLock);
MutexAutoLock lock(*sHolderLock);
sTrackersHolders[mSerial] = this;
}
}
AsyncTransactionTrackersHolder::~AsyncTransactionTrackersHolder()
@ -76,6 +87,12 @@ AsyncTransactionTrackersHolder::~AsyncTransactionTrackersHolder()
if (!mIsTrackersHolderDestroyed) {
DestroyAsyncTransactionTrackersHolder();
}
{
MOZ_ASSERT(sHolderLock);
MutexAutoLock lock(*sHolderLock);
sTrackersHolders.erase(mSerial);
}
MOZ_COUNT_DTOR(AsyncTransactionTrackersHolder);
}
@ -92,24 +109,68 @@ AsyncTransactionTrackersHolder::HoldUntilComplete(AsyncTransactionTracker* aTran
}
if (aTransactionTracker) {
MutexAutoLock lock(*sHolderLock);
mAsyncTransactionTrackeres[aTransactionTracker->GetId()] = aTransactionTracker;
}
}
void
AsyncTransactionTrackersHolder::TransactionCompleteted(uint64_t aTransactionId)
{
MutexAutoLock lock(*sHolderLock);
TransactionCompletetedInternal(aTransactionId);
}
void
AsyncTransactionTrackersHolder::TransactionCompletetedInternal(uint64_t aTransactionId)
{
std::map<uint64_t, RefPtr<AsyncTransactionTracker> >::iterator it
= mAsyncTransactionTrackeres.find(aTransactionId);
if (it != mAsyncTransactionTrackeres.end()) {
it->second->NotifyCancel();
it->second->NotifyComplete();
mAsyncTransactionTrackeres.erase(it);
}
}
void
AsyncTransactionTrackersHolder::SetReleaseFenceHandle(FenceHandle& aReleaseFenceHandle,
uint64_t aTransactionId)
{
std::map<uint64_t, RefPtr<AsyncTransactionTracker> >::iterator it
= mAsyncTransactionTrackeres.find(aTransactionId);
if (it != mAsyncTransactionTrackeres.end()) {
it->second->SetReleaseFenceHandle(aReleaseFenceHandle);
}
}
/*static*/ void
AsyncTransactionTrackersHolder::TransactionCompleteted(uint64_t aHolderId, uint64_t aTransactionId)
{
MutexAutoLock lock(*sHolderLock);
AsyncTransactionTrackersHolder* holder = sTrackersHolders[aHolderId];
if (!holder) {
return;
}
holder->TransactionCompletetedInternal(aTransactionId);
}
/*static*/ void
AsyncTransactionTrackersHolder::SetReleaseFenceHandle(FenceHandle& aReleaseFenceHandle,
uint64_t aHolderId,
uint64_t aTransactionId)
{
MutexAutoLock lock(*sHolderLock);
AsyncTransactionTrackersHolder* holder = sTrackersHolders[aHolderId];
if (!holder) {
return;
}
holder->SetReleaseFenceHandle(aReleaseFenceHandle, aTransactionId);
}
void
AsyncTransactionTrackersHolder::ClearAllAsyncTransactionTrackers()
{
MutexAutoLock lock(*sHolderLock);
std::map<uint64_t, RefPtr<AsyncTransactionTracker> >::iterator it;
for (it = mAsyncTransactionTrackeres.begin();
it != mAsyncTransactionTrackeres.end(); it++) {

View File

@ -11,6 +11,7 @@
#include <map>
#include "mozilla/Atomics.h"
#include "mozilla/layers/FenceUtils.h" // for FenceHandle
#include "mozilla/Monitor.h" // for Monitor
#include "mozilla/RefPtr.h" // for AtomicRefCounted
@ -18,6 +19,7 @@ namespace mozilla {
namespace layers {
class TextureClient;
class AsyncTransactionTrackersHolder;
/**
* AsyncTransactionTracker tracks asynchronous transaction.
@ -25,26 +27,12 @@ class TextureClient;
*/
class AsyncTransactionTracker
{
friend class AsyncTransactionTrackersHolder;
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncTransactionTracker)
AsyncTransactionTracker();
static void Initialize()
{
if (!sLock) {
sLock = new Mutex("AsyncTransactionTracker::sLock");
}
}
static void Finalize()
{
if (sLock) {
delete sLock;
sLock = nullptr;
}
}
Monitor& GetReentrantMonitor()
{
return mCompletedMonitor;
@ -83,19 +71,31 @@ public:
virtual void SetTextureClient(TextureClient* aTextureClient) {}
virtual void SetReleaseFenceHandle(FenceHandle& aReleaseFenceHandle) {}
protected:
virtual ~AsyncTransactionTracker();
static void Initialize()
{
if (!sLock) {
sLock = new Mutex("AsyncTransactionTracker::sLock");
}
}
static void Finalize()
{
if (sLock) {
delete sLock;
sLock = nullptr;
}
}
static uint64_t GetNextSerial()
{
MOZ_ASSERT(sLock);
if(sLock) {
sLock->Lock();
}
MutexAutoLock lock(*sLock);
++sSerialCounter;
if(sLock) {
sLock->Unlock();
}
return sSerialCounter;
}
@ -117,18 +117,102 @@ public:
AsyncTransactionTrackersHolder();
virtual ~AsyncTransactionTrackersHolder();
static void Initialize()
{
if (!sHolderLock) {
sHolderLock = new Mutex("AsyncTransactionTrackersHolder::sHolderLock");
}
AsyncTransactionTracker::Initialize();
}
static void Finalize()
{
if (sHolderLock) {
delete sHolderLock;
sHolderLock = nullptr;
}
AsyncTransactionTracker::Finalize();
}
void HoldUntilComplete(AsyncTransactionTracker* aTransactionTracker);
void TransactionCompleteted(uint64_t aTransactionId);
static void TransactionCompleteted(uint64_t aHolderId, uint64_t aTransactionId);
static void SetReleaseFenceHandle(FenceHandle& aReleaseFenceHandle,
uint64_t aHolderId,
uint64_t aTransactionId);
uint64_t GetId()
{
return mSerial;
}
protected:
static uint64_t GetNextSerial()
{
MOZ_ASSERT(sHolderLock);
MutexAutoLock lock(*sHolderLock);
++sSerialCounter;
return sSerialCounter;
}
void TransactionCompletetedInternal(uint64_t aTransactionId);
void SetReleaseFenceHandle(FenceHandle& aReleaseFenceHandle, uint64_t aTransactionId);
void ClearAllAsyncTransactionTrackers();
void DestroyAsyncTransactionTrackersHolder();
uint64_t mSerial;
bool mIsTrackersHolderDestroyed;
std::map<uint64_t, RefPtr<AsyncTransactionTracker> > mAsyncTransactionTrackeres;
/**
* gecko does not provide atomic operation for uint64_t.
* Ensure atomicity by using Mutex.
*/
static uint64_t sSerialCounter;
static Mutex* sHolderLock;
/**
* Map of all living AsyncTransactionTrackersHolder instances
*/
static std::map<uint64_t, AsyncTransactionTrackersHolder*> sTrackersHolders;
};
/**
* FenceDeliveryTracker puts off releasing a Fence until a transaction complete.
*/
class FenceDeliveryTracker : public AsyncTransactionTracker {
public:
FenceDeliveryTracker(FenceHandle& aFenceHandle)
: mFenceHandle(aFenceHandle)
{
MOZ_COUNT_CTOR(FenceDeliveryTracker);
}
~FenceDeliveryTracker()
{
MOZ_COUNT_DTOR(FenceDeliveryTracker);
}
virtual void Complete() MOZ_OVERRIDE
{
mFenceHandle = FenceHandle();
}
virtual void Cancel() MOZ_OVERRIDE
{
mFenceHandle = FenceHandle();
}
private:
FenceHandle mFenceHandle;
};
} // namespace layers

View File

@ -16,6 +16,7 @@
#include "mozilla/RefPtr.h" // for RefPtr
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/ContentHost.h" // for ContentHostBase
#include "mozilla/layers/ImageBridgeParent.h" // for ImageBridgeParent
#include "mozilla/layers/SharedBufferManagerParent.h"
#include "mozilla/layers/LayerManagerComposite.h"
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
@ -113,8 +114,6 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
OpContentBufferSwap(op.compositableParent(), nullptr, frontUpdatedRegion));
RenderTraceInvalidateEnd(thebes, "FF00FF");
// return texure data to client if necessary
ReturnTextureDataIfNecessary(compositable);
break;
}
case CompositableOperation::TOpPaintTextureIncremental: {
@ -159,14 +158,8 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
MOZ_ASSERT(tex.get());
compositable->RemoveTextureHost(tex);
// return texure data to client if necessary
if (IsAsync()) {
DeprecatedReturnTextureDataIfNecessary(compositable,
replyv,
op.compositableParent());
} else {
ReturnTextureDataIfNecessary(compositable);
}
// send FenceHandle if present.
TextureHost::SendFenceHandleIfPresent(op.textureParent());
break;
}
case CompositableOperation::TOpRemoveTextureAsync: {
@ -176,12 +169,30 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
MOZ_ASSERT(tex.get());
compositable->RemoveTextureHost(tex);
// send FenceHandle if present.
TextureHost::SendFenceHandleIfPresent(op.textureParent());
ReplyRemoveTexture(OpReplyRemoveTexture(op.transactionId(),
op.compositableParent(), nullptr,
tex->GetIPDLActor(), nullptr));
if (!IsAsync() && GetChildProcessId()) {
// send FenceHandle if present via ImageBridge.
ImageBridgeParent::SendFenceHandleToTrackerIfPresent(
GetChildProcessId(),
op.holderId(),
op.transactionId(),
op.textureParent());
// If the message is recievied via PLayerTransaction,
// Send message back via PImageBridge.
ImageBridgeParent::ReplyRemoveTexture(
GetChildProcessId(),
OpReplyRemoveTexture(true, // isMain
op.holderId(),
op.transactionId()));
} else {
// send FenceHandle if present.
TextureHost::SendFenceHandleIfPresent(op.textureParent());
ReplyRemoveTexture(OpReplyRemoveTexture(false, // isMain
op.holderId(),
op.transactionId()));
}
break;
}
case CompositableOperation::TOpUseTexture: {
@ -200,14 +211,6 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
compositable->GetLayer()->SetInvalidRectToVisibleRegion();
}
}
// return texure data to client if necessary
if (IsAsync()) {
DeprecatedReturnTextureDataIfNecessary(compositable,
replyv,
op.compositableParent());
} else {
ReturnTextureDataIfNecessary(compositable);
}
break;
}
case CompositableOperation::TOpUseComponentAlphaTextures: {
@ -222,8 +225,6 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
if (IsAsync()) {
ScheduleComposition(op);
}
// return texure data to client if necessary
ReturnTextureDataIfNecessary(compositable);
break;
}
case CompositableOperation::TOpUpdateTexture: {
@ -245,112 +246,6 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
return true;
}
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
void
CompositableParentManager::ReturnTextureDataIfNecessary(CompositableHost* aCompositable)
{
if (!aCompositable || !aCompositable->GetCompositableBackendSpecificData()) {
return;
}
static const uint32_t MAX_FENCE_COUNT_PER_MESSAGE = 4;
const std::vector< RefPtr<TextureHost> > textureList =
aCompositable->GetCompositableBackendSpecificData()->GetPendingReleaseFenceTextureList();
InfallibleTArray<AsyncParentMessageData> messages;
messages.SetCapacity(MAX_FENCE_COUNT_PER_MESSAGE);
// Send Fences to child side
for (size_t i = 0; i < textureList.size(); i++) {
TextureHostOGL* hostOGL = textureList[i]->AsHostOGL();
PTextureParent* actor = textureList[i]->GetIPDLActor();
if (!hostOGL || !actor) {
continue;
}
android::sp<android::Fence> fence = hostOGL->GetAndResetReleaseFence();
if (fence.get() && fence->isValid()) {
RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(fence);
FenceHandle handle = FenceHandle(fence);
HoldUntilComplete(tracker);
messages.AppendElement(OpDeliverFence(tracker->GetId(),
actor, nullptr,
handle));
if (messages.Length() >= MAX_FENCE_COUNT_PER_MESSAGE) {
SendAsyncMessage(messages);
messages.Clear();
}
}
}
if (messages.Length() > 0) {
SendAsyncMessage(messages);
messages.Clear();
}
aCompositable->GetCompositableBackendSpecificData()->ClearPendingReleaseFenceTextureList();
}
void
CompositableParentManager::DeprecatedReturnTextureDataIfNecessary(CompositableHost* aCompositable,
EditReplyVector& replyv,
PCompositableParent* aParent)
{
if (!aCompositable || !aCompositable->GetCompositableBackendSpecificData()) {
return;
}
const std::vector< RefPtr<TextureHost> > textureList =
aCompositable->GetCompositableBackendSpecificData()->GetPendingReleaseFenceTextureList();
// Return pending Texture data
for (size_t i = 0; i < textureList.size(); i++) {
// File descriptor number is limited to 4 per IPC message.
// See Bug 986253
if (mPrevFenceHandles.size() >= 4) {
break;
}
TextureHostOGL* hostOGL = textureList[i]->AsHostOGL();
PTextureParent* actor = textureList[i]->GetIPDLActor();
if (!hostOGL || !actor) {
continue;
}
android::sp<android::Fence> fence = hostOGL->GetAndResetReleaseFence();
if (fence.get() && fence->isValid()) {
FenceHandle handle = FenceHandle(fence);
replyv.push_back(ReturnReleaseFence(aParent, nullptr, actor, nullptr, handle));
// Hold fence handle to prevent fence's file descriptor is closed before IPC happens.
mPrevFenceHandles.push_back(handle);
}
}
aCompositable->GetCompositableBackendSpecificData()->ClearPendingReleaseFenceTextureList();
}
#else
void
CompositableParentManager::ReturnTextureDataIfNecessary(CompositableHost* aCompositable)
{
if (!aCompositable || !aCompositable->GetCompositableBackendSpecificData()) {
return;
}
aCompositable->GetCompositableBackendSpecificData()->ClearPendingReleaseFenceTextureList();
}
void
CompositableParentManager::DeprecatedReturnTextureDataIfNecessary(CompositableHost* aCompositable,
EditReplyVector& replyv,
PCompositableParent* aParent)
{
if (!aCompositable || !aCompositable->GetCompositableBackendSpecificData()) {
return;
}
aCompositable->GetCompositableBackendSpecificData()->ClearPendingReleaseFenceTextureList();
}
#endif
void
CompositableParentManager::DeprecatedClearPrevFenceHandles()
{
mPrevFenceHandles.clear();
}
} // namespace
} // namespace

View File

@ -36,6 +36,11 @@ public:
virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) = 0;
/**
* Get child side's process Id.
*/
virtual base::ProcessId GetChildProcessId() = 0;
protected:
/**
* Handle the IPDL messages that affect PCompositable actors.
@ -50,17 +55,8 @@ protected:
*/
virtual bool IsAsync() const { return false; }
void ReturnTextureDataIfNecessary(CompositableHost* aCompositable);
void DeprecatedReturnTextureDataIfNecessary(CompositableHost* aCompositable,
EditReplyVector& replyv,
PCompositableParent* aParent);
void DeprecatedClearPrevFenceHandles();
virtual void ReplyRemoveTexture(const OpReplyRemoveTexture& aReply) {}
protected:
std::vector<FenceHandle> mPrevFenceHandles;
};
} // namespace

View File

@ -932,7 +932,9 @@ CompositorParent::AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aB
if (!mLayerManager) {
NS_WARNING("Failed to initialise Compositor");
*aSuccess = false;
LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, 0);
LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, 0,
// child side's process id is current process Id
base::GetProcId(base::GetCurrentProcessHandle()));
p->AddIPDLReference();
return p;
}
@ -941,7 +943,9 @@ CompositorParent::AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aB
*aSuccess = true;
*aTextureFactoryIdentifier = mCompositor->GetTextureFactoryIdentifier();
LayerTransactionParent* p = new LayerTransactionParent(mLayerManager, this, 0);
LayerTransactionParent* p = new LayerTransactionParent(mLayerManager, this, 0,
// child side's process id is current process Id
base::GetProcId(base::GetCurrentProcessHandle()));
p->AddIPDLReference();
return p;
}
@ -1111,8 +1115,9 @@ class CrossProcessCompositorParent MOZ_FINAL : public PCompositorParent,
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CrossProcessCompositorParent)
public:
CrossProcessCompositorParent(Transport* aTransport)
CrossProcessCompositorParent(Transport* aTransport, ProcessId aOtherProcess)
: mTransport(aTransport)
, mChildProcessId(aOtherProcess)
{}
// IToplevelProtocol::CloneToplevel()
@ -1171,6 +1176,8 @@ private:
// ourself. This is released (deferred) in ActorDestroy().
nsRefPtr<CrossProcessCompositorParent> mSelfRef;
Transport* mTransport;
// Child side's process Id.
base::ProcessId mChildProcessId;
};
static void
@ -1186,7 +1193,7 @@ OpenCompositor(CrossProcessCompositorParent* aCompositor,
CompositorParent::Create(Transport* aTransport, ProcessId aOtherProcess)
{
nsRefPtr<CrossProcessCompositorParent> cpcp =
new CrossProcessCompositorParent(aTransport);
new CrossProcessCompositorParent(aTransport, aOtherProcess);
ProcessHandle handle;
if (!base::OpenProcessHandle(aOtherProcess, &handle)) {
// XXX need to kill |aOtherProcess|, it's boned
@ -1272,7 +1279,7 @@ CrossProcessCompositorParent::AllocPLayerTransactionParent(const nsTArray<Layers
LayerManagerComposite* lm = state->mLayerManager;
*aTextureFactoryIdentifier = lm->GetCompositor()->GetTextureFactoryIdentifier();
*aSuccess = true;
LayerTransactionParent* p = new LayerTransactionParent(lm, this, aId);
LayerTransactionParent* p = new LayerTransactionParent(lm, this, aId, mChildProcessId);
p->AddIPDLReference();
return p;
}
@ -1281,7 +1288,7 @@ CrossProcessCompositorParent::AllocPLayerTransactionParent(const nsTArray<Layers
// XXX: should be false, but that causes us to fail some tests on Mac w/ OMTC.
// Bug 900745. change *aSuccess to false to see test failures.
*aSuccess = true;
LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, aId);
LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, aId, mChildProcessId);
p->AddIPDLReference();
return p;
}

View File

@ -12,7 +12,6 @@
#include <ui/Fence.h>
#include "ipc/IPCMessageUtils.h"
#include "mozilla/layers/AsyncTransactionTracker.h" // for AsyncTransactionTracker
namespace mozilla {
namespace layers {
@ -36,34 +35,6 @@ struct FenceHandle {
android::sp<Fence> mFence;
};
// FenceDeliveryTracker puts off releasing a Fence until a transaction complete.
class FenceDeliveryTracker : public AsyncTransactionTracker {
public:
FenceDeliveryTracker(const android::sp<android::Fence>& aFence)
: mFence(aFence)
{
MOZ_COUNT_CTOR(FenceDeliveryTracker);
}
~FenceDeliveryTracker()
{
MOZ_COUNT_DTOR(FenceDeliveryTracker);
}
virtual void Complete() MOZ_OVERRIDE
{
mFence = nullptr;
}
virtual void Cancel() MOZ_OVERRIDE
{
mFence = nullptr;
}
private:
android::sp<android::Fence> mFence;
};
} // namespace layers
} // namespace mozilla

View File

@ -597,7 +597,7 @@ bool ImageBridgeChild::StartUpOnThread(Thread* aThread)
}
sImageBridgeChildSingleton = new ImageBridgeChild();
sImageBridgeParentSingleton = new ImageBridgeParent(
CompositorParent::CompositorLoop(), nullptr);
CompositorParent::CompositorLoop(), nullptr, base::GetProcId(base::GetCurrentProcessHandle()));
sImageBridgeChildSingleton->ConnectAsync(sImageBridgeParentSingleton);
return true;
} else {
@ -820,10 +820,24 @@ ImageBridgeChild::RecvParentAsyncMessage(const InfallibleTArray<AsyncParentMessa
HoldTransactionsToRespond(op.transactionId());
break;
}
case AsyncParentMessageData::TOpReplyRemoveTexture: {
const OpReplyRemoveTexture& op = message.get_OpReplyRemoveTexture();
case AsyncParentMessageData::TOpDeliverFenceToTracker: {
const OpDeliverFenceToTracker& op = message.get_OpDeliverFenceToTracker();
FenceHandle fence = op.fence();
CompositableClient::TransactionCompleteted(op.compositableChild(), op.transactionId());
AsyncTransactionTrackersHolder::SetReleaseFenceHandle(fence,
op.destHolderId(),
op.destTransactionId());
// Send back a response.
InfallibleTArray<AsyncChildMessageData> replies;
replies.AppendElement(OpReplyDeliverFence(op.transactionId()));
SendChildAsyncMessages(replies);
break;
}
case AsyncParentMessageData::TOpReplyRemoveTexture: {
const OpReplyRemoveTexture& op = message.get_OpReplyRemoveTexture();
AsyncTransactionTrackersHolder::TransactionCompleteted(op.holderId(),
op.transactionId());
break;
}
default:
@ -863,15 +877,13 @@ ImageBridgeChild::RemoveTextureFromCompositableAsync(AsyncTransactionTracker* aA
CompositableClient* aCompositable,
TextureClient* aTexture)
{
mTxn->AddNoSwapEdit(OpRemoveTextureAsync(aAsyncTransactionTracker->GetId(),
mTxn->AddNoSwapEdit(OpRemoveTextureAsync(CompositableClient::GetTrackersHolderId(aCompositable->GetIPDLActor()),
aAsyncTransactionTracker->GetId(),
nullptr, aCompositable->GetIPDLActor(),
nullptr, aTexture->GetIPDLActor()));
// Hold AsyncTransactionTracker until receving reply
CompositableClient::HoldUntilComplete(aCompositable->GetIPDLActor(),
aAsyncTransactionTracker);
// Hold texture until transaction complete.
HoldUntilTransaction(aTexture);
}
static void RemoveTextureSync(TextureClient* aTexture, ReentrantMonitor* aBarrier, bool* aDone)

View File

@ -41,13 +41,19 @@ namespace layers {
using namespace mozilla::ipc;
using namespace mozilla::gfx;
ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop, Transport* aTransport)
std::map<base::ProcessId, ImageBridgeParent*> ImageBridgeParent::sImageBridges;
ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop,
Transport* aTransport,
ProcessId aChildProcessId)
: mMessageLoop(aLoop)
, mTransport(aTransport)
, mChildProcessId(aChildProcessId)
{
// creates the map only if it has not been created already, so it is safe
// with several bridges
CompositableMap::Create();
sImageBridges[aChildProcessId] = this;
}
ImageBridgeParent::~ImageBridgeParent()
@ -56,6 +62,7 @@ ImageBridgeParent::~ImageBridgeParent()
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
new DeleteTask<Transport>(mTransport));
}
sImageBridges.erase(mChildProcessId);
}
LayersBackend
@ -81,9 +88,6 @@ ImageBridgeParent::RecvUpdate(const EditArray& aEdits, EditReplyArray* aReply)
return true;
}
// Clear fence handles used in previsou transaction.
DeprecatedClearPrevFenceHandles();
EditReplyVector replyv;
for (EditArray::index_type i = 0; i < aEdits.Length(); ++i) {
if (!ReceiveCompositableUpdate(aEdits[i], replyv)) {
@ -122,15 +126,15 @@ ConnectImageBridgeInParentProcess(ImageBridgeParent* aBridge,
}
/*static*/ PImageBridgeParent*
ImageBridgeParent::Create(Transport* aTransport, ProcessId aOtherProcess)
ImageBridgeParent::Create(Transport* aTransport, ProcessId aChildProcessId)
{
base::ProcessHandle processHandle;
if (!base::OpenProcessHandle(aOtherProcess, &processHandle)) {
if (!base::OpenProcessHandle(aChildProcessId, &processHandle)) {
return nullptr;
}
MessageLoop* loop = CompositorParent::CompositorLoop();
nsRefPtr<ImageBridgeParent> bridge = new ImageBridgeParent(loop, aTransport);
nsRefPtr<ImageBridgeParent> bridge = new ImageBridgeParent(loop, aTransport, aChildProcessId);
bridge->mSelfRef = bridge;
loop->PostTask(FROM_HERE,
NewRunnableFunction(ConnectImageBridgeInParentProcess,
@ -265,6 +269,13 @@ ImageBridgeParent::DeferredDestroy()
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(runnable)));
}
ImageBridgeParent*
ImageBridgeParent::GetInstance(ProcessId aId)
{
NS_ASSERTION(sImageBridges.count(aId) == 1, "ImageBridgeParent for the process");
return sImageBridges[aId];
}
IToplevelProtocol*
ImageBridgeParent::CloneToplevel(const InfallibleTArray<ProtocolFdMapping>& aFds,
base::ProcessHandle aPeerProcess,
@ -296,5 +307,56 @@ ImageBridgeParent::ReplyRemoveTexture(const OpReplyRemoveTexture& aReply)
mozilla::unused << SendParentAsyncMessage(messages);
}
/*static*/ void
ImageBridgeParent::ReplyRemoveTexture(base::ProcessId aChildProcessId,
const OpReplyRemoveTexture& aReply)
{
ImageBridgeParent* imageBridge = ImageBridgeParent::GetInstance(aChildProcessId);
if (!imageBridge) {
return;
}
imageBridge->ReplyRemoveTexture(aReply);
}
/*static*/ void
ImageBridgeParent::SendFenceHandleToTrackerIfPresent(uint64_t aDestHolderId,
uint64_t aTransactionId,
PTextureParent* aTexture)
{
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
if (!texture) {
return;
}
FenceHandle fence = texture->GetAndResetReleaseFenceHandle();
if (!fence.IsValid()) {
return;
}
RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(fence);
HoldUntilComplete(tracker);
InfallibleTArray<AsyncParentMessageData> messages;
messages.AppendElement(OpDeliverFenceToTracker(tracker->GetId(),
aDestHolderId,
aTransactionId,
fence));
mozilla::unused << SendParentAsyncMessage(messages);
}
/*static*/ void
ImageBridgeParent::SendFenceHandleToTrackerIfPresent(base::ProcessId aChildProcessId,
uint64_t aDestHolderId,
uint64_t aTransactionId,
PTextureParent* aTexture)
{
ImageBridgeParent* imageBridge = ImageBridgeParent::GetInstance(aChildProcessId);
if (!imageBridge) {
return;
}
imageBridge->SendFenceHandleToTrackerIfPresent(aDestHolderId,
aTransactionId,
aTexture);
}
} // layers
} // mozilla

View File

@ -44,7 +44,7 @@ public:
typedef InfallibleTArray<EditReply> EditReplyArray;
typedef InfallibleTArray<AsyncChildMessageData> AsyncChildMessageArray;
ImageBridgeParent(MessageLoop* aLoop, Transport* aTransport);
ImageBridgeParent(MessageLoop* aLoop, Transport* aTransport, ProcessId aChildProcessId);
~ImageBridgeParent();
virtual LayersBackend GetCompositorBackendType() const MOZ_OVERRIDE;
@ -52,7 +52,7 @@ public:
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
static PImageBridgeParent*
Create(Transport* aTransport, ProcessId aOtherProcess);
Create(Transport* aTransport, ProcessId aChildProcessId);
// CompositableParentManager
virtual void SendFenceHandle(AsyncTransactionTracker* aTracker,
@ -61,6 +61,11 @@ public:
virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) MOZ_OVERRIDE;
virtual base::ProcessId GetChildProcessId() MOZ_OVERRIDE
{
return mChildProcessId;
}
// PImageBridge
virtual bool RecvUpdate(const EditArray& aEdits, EditReplyArray* aReply) MOZ_OVERRIDE;
virtual bool RecvUpdateNoSwap(const EditArray& aEdits) MOZ_OVERRIDE;
@ -111,6 +116,20 @@ public:
virtual void ReplyRemoveTexture(const OpReplyRemoveTexture& aReply) MOZ_OVERRIDE;
static void ReplyRemoveTexture(base::ProcessId aChildProcessId,
const OpReplyRemoveTexture& aReply);
void SendFenceHandleToTrackerIfPresent(uint64_t aDestHolderId,
uint64_t aTransactionId,
PTextureParent* aTexture);
static void SendFenceHandleToTrackerIfPresent(base::ProcessId aChildProcessId,
uint64_t aDestHolderId,
uint64_t aTransactionId,
PTextureParent* aTexture);
static ImageBridgeParent* GetInstance(ProcessId aId);
// Overriden from IToplevelProtocol
IToplevelProtocol*
CloneToplevel(const InfallibleTArray<ProtocolFdMapping>& aFds,
@ -122,9 +141,16 @@ private:
MessageLoop* mMessageLoop;
Transport* mTransport;
// Child side's process id.
base::ProcessId mChildProcessId;
// This keeps us alive until ActorDestroy(), at which point we do a
// deferred destruction of ourselves.
nsRefPtr<ImageBridgeParent> mSelfRef;
/**
* Map of all living ImageBridgeParent instances
*/
static std::map<base::ProcessId, ImageBridgeParent*> sImageBridges;
};
} // layers

View File

@ -143,10 +143,12 @@ ShadowChild(const OpRaiseToTopChild& op)
// LayerTransactionParent
LayerTransactionParent::LayerTransactionParent(LayerManagerComposite* aManager,
ShadowLayersManager* aLayersManager,
uint64_t aId)
uint64_t aId,
ProcessId aOtherProcess)
: mLayerManager(aManager)
, mShadowLayersManager(aLayersManager)
, mId(aId)
, mChildProcessId(aOtherProcess)
, mDestroyed(false)
, mIPCOpen(false)
{
@ -211,9 +213,6 @@ LayerTransactionParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
mLayerManager->GetCompositor()->SetScreenRotation(targetConfig.rotation());
}
// Clear fence handles used in previsou transaction.
DeprecatedClearPrevFenceHandles();
EditReplyVector replyv;
{

View File

@ -48,7 +48,8 @@ class LayerTransactionParent : public PLayerTransactionParent,
public:
LayerTransactionParent(LayerManagerComposite* aManager,
ShadowLayersManager* aLayersManager,
uint64_t aId);
uint64_t aId,
ProcessId aOtherProcess);
~LayerTransactionParent();
void Destroy();
@ -87,6 +88,11 @@ public:
virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) MOZ_OVERRIDE;
virtual base::ProcessId GetChildProcessId() MOZ_OVERRIDE
{
return mChildProcessId;
}
protected:
virtual bool RecvUpdate(const EditArray& cset,
const TargetConfig& targetConfig,
@ -171,6 +177,10 @@ private:
// called on us but the mLayerManager might not be destroyed, or
// vice versa. In both cases though, we want to ignore shadow-layer
// transactions posted by the child.
// Child side's process id.
base::ProcessId mChildProcessId;
bool mDestroyed;
bool mIPCOpen;

View File

@ -334,15 +334,16 @@ struct OpRemoveTexture {
};
struct OpRemoveTextureAsync {
uint64_t holderId;
uint64_t transactionId;
PCompositable compositable;
PTexture texture;
};
struct OpReplyRemoveTexture {
bool isMain;
uint64_t holderId;
uint64_t transactionId;
PCompositable compositable;
PTexture texture;
};
/**
@ -377,6 +378,13 @@ struct OpDeliverFence {
FenceHandle fence;
};
struct OpDeliverFenceToTracker {
uint64_t transactionId;
uint64_t destHolderId;
uint64_t destTransactionId;
FenceHandle fence;
};
struct OpReplyDeliverFence {
uint64_t transactionId;
};
@ -455,6 +463,7 @@ union EditReply {
union AsyncParentMessageData {
OpDeliverFence;
OpDeliverFenceToTracker;
OpReplyRemoveTexture;
};

View File

@ -427,6 +427,20 @@ ShadowLayerForwarder::RemoveTextureFromCompositable(CompositableClient* aComposi
HoldUntilTransaction(aTexture);
}
void
ShadowLayerForwarder::RemoveTextureFromCompositableAsync(AsyncTransactionTracker* aAsyncTransactionTracker,
CompositableClient* aCompositable,
TextureClient* aTexture)
{
mTxn->AddEdit(OpRemoveTextureAsync(CompositableClient::GetTrackersHolderId(aCompositable->GetIPDLActor()),
aAsyncTransactionTracker->GetId(),
nullptr, aCompositable->GetIPDLActor(),
nullptr, aTexture->GetIPDLActor()));
// Hold AsyncTransactionTracker until receving reply
CompositableClient::HoldUntilComplete(aCompositable->GetIPDLActor(),
aAsyncTransactionTracker);
}
void
ShadowLayerForwarder::RemoveTexture(TextureClient* aTexture)
{

View File

@ -245,6 +245,10 @@ public:
virtual void RemoveTextureFromCompositable(CompositableClient* aCompositable,
TextureClient* aTexture) MOZ_OVERRIDE;
virtual void RemoveTextureFromCompositableAsync(AsyncTransactionTracker* aAsyncTransactionTracker,
CompositableClient* aCompositable,
TextureClient* aTexture) MOZ_OVERRIDE;
virtual void RemoveTexture(TextureClient* aTexture) MOZ_OVERRIDE;
/**

View File

@ -6,6 +6,7 @@
#ifdef MOZ_WIDGET_GONK
#include "mozilla/gfx/2D.h"
#include "mozilla/layers/AsyncTransactionTracker.h" // for AsyncTransactionTracker
#include "mozilla/layers/GrallocTextureClient.h"
#include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/layers/ISurfaceAllocator.h"
@ -81,8 +82,19 @@ GrallocTextureClientOGL::SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle)
}
void
GrallocTextureClientOGL::WaitReleaseFence()
GrallocTextureClientOGL::SetRemoveFromCompositableTracker(AsyncTransactionTracker* aTracker)
{
mRemoveFromCompositableTracker = aTracker;
}
void
GrallocTextureClientOGL::WaitForBufferOwnership()
{
if (mRemoveFromCompositableTracker) {
mRemoveFromCompositableTracker->WaitComplete();
mRemoveFromCompositableTracker = nullptr;
}
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
if (mReleaseFenceHandle.IsValid()) {
android::sp<Fence> fence = mReleaseFenceHandle.mFence;
@ -110,7 +122,7 @@ GrallocTextureClientOGL::Lock(OpenMode aMode)
return true;
}
WaitReleaseFence();
WaitForBufferOwnership();
uint32_t usage = 0;
if (aMode & OpenMode::OPEN_READ) {

View File

@ -62,7 +62,9 @@ public:
virtual void SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle) MOZ_OVERRIDE;
virtual void WaitReleaseFence() MOZ_OVERRIDE;
virtual void SetRemoveFromCompositableTracker(AsyncTransactionTracker* aTracker) MOZ_OVERRIDE;
virtual void WaitForBufferOwnership() MOZ_OVERRIDE;
void InitWith(MaybeMagicGrallocBufferHandle aDesc, gfx::IntSize aSize);
@ -120,6 +122,8 @@ protected:
*/
MaybeMagicGrallocBufferHandle mGrallocHandle;
RefPtr<AsyncTransactionTracker> mRemoveFromCompositableTracker;
android::sp<android::GraphicBuffer> mGraphicBuffer;
/**

View File

@ -455,11 +455,6 @@ GrallocTextureHostOGL::SetCompositableBackendSpecificData(CompositableBackendSpe
if (mTextureSource) {
mTextureSource->SetCompositableBackendSpecificData(aBackendData);
}
// Register this object to CompositableBackendSpecificData
// as current TextureHost.
if (aBackendData) {
aBackendData->SetCurrentReleaseFenceTexture(this);
}
}
} // namepsace layers

View File

@ -336,7 +336,7 @@ gfxPlatform::Init()
gGfxPlatformPrefsLock = new Mutex("gfxPlatform::gGfxPlatformPrefsLock");
AsyncTransactionTracker::Initialize();
AsyncTransactionTrackersHolder::Initialize();
/* Initialize the GfxInfo service.
* Note: we can't call functions on GfxInfo that depend

View File

@ -993,7 +993,7 @@ RenderFrameParent::AllocPLayerTransactionParent()
return nullptr;
}
nsRefPtr<LayerManager> lm = GetFrom(mFrameLoader);
LayerTransactionParent* result = new LayerTransactionParent(lm->AsLayerManagerComposite(), this, 0);
LayerTransactionParent* result = new LayerTransactionParent(lm->AsLayerManagerComposite(), this, 0, 0);
result->AddIPDLReference();
return result;
}

View File

@ -812,7 +812,7 @@ ShutdownXPCOM(nsIServiceManager* servMgr)
nullptr);
layers::CompositorParent::ShutDown();
layers::AsyncTransactionTracker::Finalize();
layers::AsyncTransactionTrackersHolder::Finalize();
gXPCOMThreadsShutDown = true;
NS_ProcessPendingEvents(thread);