зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1006957 - Handle buffer ownership between SurfaceStream and CanvasClient r=nical
This commit is contained in:
Родитель
095d4eb7ff
Коммит
ac5d74bdb6
|
@ -210,7 +210,7 @@ SharedSurface_Gralloc::WaitSync()
|
|||
void
|
||||
SharedSurface_Gralloc::WaitForBufferOwnership()
|
||||
{
|
||||
mTextureClient->WaitReleaseFence();
|
||||
mTextureClient->WaitForBufferOwnership();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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:
|
||||
/**
|
||||
|
|
|
@ -44,7 +44,7 @@ TextureClientPool::GetTextureClient()
|
|||
RefPtr<TextureClient> textureClient;
|
||||
if (mTextureClients.size()) {
|
||||
textureClient = mTextureClients.top();
|
||||
textureClient->WaitReleaseFence();
|
||||
textureClient->WaitForBufferOwnership();
|
||||
mTextureClients.pop();
|
||||
return textureClient;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -812,7 +812,7 @@ ShutdownXPCOM(nsIServiceManager* servMgr)
|
|||
nullptr);
|
||||
|
||||
layers::CompositorParent::ShutDown();
|
||||
layers::AsyncTransactionTracker::Finalize();
|
||||
layers::AsyncTransactionTrackersHolder::Finalize();
|
||||
|
||||
gXPCOMThreadsShutDown = true;
|
||||
NS_ProcessPendingEvents(thread);
|
||||
|
|
Загрузка…
Ссылка в новой задаче