зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1143575. Factor out AsyncTransactionWaiter from AsyncTransactionTracker so we'll be able to wait for multiple AsyncTransactionTrackers. r=nical,sotaro
--HG-- extra : commitid : KV6Mne8t10A extra : rebase_source : 02de1f49ce13465481cfa688b8867fc558cac474
This commit is contained in:
Родитель
4b6793f937
Коммит
7f3db8a464
|
@ -34,7 +34,8 @@ class PCompositableChild;
|
|||
*/
|
||||
class RemoveTextureFromCompositableTracker : public AsyncTransactionTracker {
|
||||
public:
|
||||
RemoveTextureFromCompositableTracker()
|
||||
explicit RemoveTextureFromCompositableTracker(AsyncTransactionWaiter* aWaiter = nullptr)
|
||||
: AsyncTransactionTracker(aWaiter)
|
||||
{
|
||||
MOZ_COUNT_CTOR(RemoveTextureFromCompositableTracker);
|
||||
}
|
||||
|
|
|
@ -442,20 +442,24 @@ ContentClientDoubleBuffered::Updated(const nsIntRegion& aRegionToDraw,
|
|||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
|
||||
if (mFrontClient) {
|
||||
// remove old buffer from CompositableHost
|
||||
RefPtr<AsyncTransactionTracker> tracker = new RemoveTextureFromCompositableTracker();
|
||||
RefPtr<AsyncTransactionWaiter> waiter = new AsyncTransactionWaiter();
|
||||
RefPtr<AsyncTransactionTracker> tracker =
|
||||
new RemoveTextureFromCompositableTracker(waiter);
|
||||
// Hold TextureClient until transaction complete.
|
||||
tracker->SetTextureClient(mFrontClient);
|
||||
mFrontClient->SetRemoveFromCompositableTracker(tracker);
|
||||
mFrontClient->SetRemoveFromCompositableWaiter(waiter);
|
||||
// RemoveTextureFromCompositableAsync() expects CompositorChild's presence.
|
||||
GetForwarder()->RemoveTextureFromCompositableAsync(tracker, this, mFrontClient);
|
||||
}
|
||||
|
||||
if (mFrontClientOnWhite) {
|
||||
// remove old buffer from CompositableHost
|
||||
RefPtr<AsyncTransactionTracker> tracker = new RemoveTextureFromCompositableTracker();
|
||||
RefPtr<AsyncTransactionWaiter> waiter = new AsyncTransactionWaiter();
|
||||
RefPtr<AsyncTransactionTracker> tracker =
|
||||
new RemoveTextureFromCompositableTracker(waiter);
|
||||
// Hold TextureClient until transaction complete.
|
||||
tracker->SetTextureClient(mFrontClientOnWhite);
|
||||
mFrontClientOnWhite->SetRemoveFromCompositableTracker(tracker);
|
||||
mFrontClientOnWhite->SetRemoveFromCompositableWaiter(waiter);
|
||||
// RemoveTextureFromCompositableAsync() expects CompositorChild's presence.
|
||||
GetForwarder()->RemoveTextureFromCompositableAsync(tracker, this, mFrontClientOnWhite);
|
||||
}
|
||||
|
|
|
@ -74,21 +74,18 @@ ImageClient::CreateImageClient(CompositableType aCompositableHostType,
|
|||
void
|
||||
ImageClient::RemoveTexture(TextureClient* aTexture)
|
||||
{
|
||||
RemoveTextureWithTracker(aTexture, nullptr);
|
||||
RemoveTextureWithWaiter(aTexture);
|
||||
}
|
||||
|
||||
void
|
||||
ImageClient::RemoveTextureWithTracker(TextureClient* aTexture,
|
||||
AsyncTransactionTracker* aAsyncTransactionTracker)
|
||||
ImageClient::RemoveTextureWithWaiter(TextureClient* aTexture,
|
||||
AsyncTransactionWaiter* aAsyncTransactionWaiter)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
if (aAsyncTransactionTracker ||
|
||||
if (aAsyncTransactionWaiter ||
|
||||
GetForwarder()->IsImageBridgeChild()) {
|
||||
RefPtr<AsyncTransactionTracker> request = aAsyncTransactionTracker;
|
||||
if (!request) {
|
||||
// Create AsyncTransactionTracker if it is not provided as argument.
|
||||
request = new RemoveTextureFromCompositableTracker();
|
||||
}
|
||||
RefPtr<AsyncTransactionTracker> request =
|
||||
new RemoveTextureFromCompositableTracker(aAsyncTransactionWaiter);
|
||||
// Hold TextureClient until the transaction complete to postpone
|
||||
// the TextureClient recycle/delete.
|
||||
request->SetTextureClient(aTexture);
|
||||
|
@ -98,11 +95,6 @@ ImageClient::RemoveTextureWithTracker(TextureClient* aTexture,
|
|||
#endif
|
||||
|
||||
GetForwarder()->RemoveTextureFromCompositable(this, aTexture);
|
||||
if (aAsyncTransactionTracker) {
|
||||
// Do not need to wait a transaction complete message
|
||||
// from the compositor side.
|
||||
aAsyncTransactionTracker->NotifyComplete();
|
||||
}
|
||||
}
|
||||
|
||||
ImageClientSingle::ImageClientSingle(CompositableForwarder* aFwd,
|
||||
|
@ -117,22 +109,13 @@ TextureInfo ImageClientSingle::GetTextureInfo() const
|
|||
return TextureInfo(CompositableType::IMAGE);
|
||||
}
|
||||
|
||||
already_AddRefed<AsyncTransactionTracker>
|
||||
ImageClientSingle::PrepareFlushAllImages()
|
||||
{
|
||||
return MakeAndAddRef<RemoveTextureFromCompositableTracker>();
|
||||
}
|
||||
|
||||
void
|
||||
ImageClientSingle::FlushAllImages(bool aExceptFront,
|
||||
AsyncTransactionTracker* aAsyncTransactionTracker)
|
||||
AsyncTransactionWaiter* aAsyncTransactionWaiter)
|
||||
{
|
||||
if (!aExceptFront && mFrontBuffer) {
|
||||
RemoveTextureWithTracker(mFrontBuffer, aAsyncTransactionTracker);
|
||||
RemoveTextureWithWaiter(mFrontBuffer, aAsyncTransactionWaiter);
|
||||
mFrontBuffer = nullptr;
|
||||
} else if (aAsyncTransactionTracker) {
|
||||
// already flushed
|
||||
aAsyncTransactionTracker->NotifyComplete();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,22 +61,17 @@ public:
|
|||
void SetLayer(ClientLayer* aLayer) { mLayer = aLayer; }
|
||||
ClientLayer* GetLayer() const { return mLayer; }
|
||||
|
||||
/**
|
||||
* Create AsyncTransactionTracker that is used for FlushAllImagesAsync().
|
||||
*/
|
||||
virtual already_AddRefed<AsyncTransactionTracker> PrepareFlushAllImages() { return nullptr; }
|
||||
|
||||
/**
|
||||
* asynchronously remove all the textures used by the image client.
|
||||
*
|
||||
*/
|
||||
virtual void FlushAllImages(bool aExceptFront,
|
||||
AsyncTransactionTracker* aAsyncTransactionTracker) {}
|
||||
AsyncTransactionWaiter* aAsyncTransactionWaiter) {}
|
||||
|
||||
virtual void RemoveTexture(TextureClient* aTexture) override;
|
||||
|
||||
void RemoveTextureWithTracker(TextureClient* aTexture,
|
||||
AsyncTransactionTracker* aAsyncTransactionTracker = nullptr);
|
||||
void RemoveTextureWithWaiter(TextureClient* aTexture,
|
||||
AsyncTransactionWaiter* aAsyncTransactionWaiter = nullptr);
|
||||
|
||||
protected:
|
||||
ImageClient(CompositableForwarder* aFwd, TextureFlags aFlags,
|
||||
|
@ -107,10 +102,8 @@ public:
|
|||
|
||||
virtual already_AddRefed<Image> CreateImage(ImageFormat aFormat) override;
|
||||
|
||||
virtual already_AddRefed<AsyncTransactionTracker> PrepareFlushAllImages() override;
|
||||
|
||||
virtual void FlushAllImages(bool aExceptFront,
|
||||
AsyncTransactionTracker* aAsyncTransactionTracker) override;
|
||||
AsyncTransactionWaiter* aAsyncTransactionWaiter) override;
|
||||
|
||||
protected:
|
||||
RefPtr<TextureClient> mFrontBuffer;
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace mozilla {
|
|||
|
||||
namespace layers {
|
||||
|
||||
class AsyncTransactionTracker;
|
||||
class AsyncTransactionWaiter;
|
||||
class CompositableForwarder;
|
||||
class ISurfaceAllocator;
|
||||
class CompositableClient;
|
||||
|
@ -448,7 +448,7 @@ public:
|
|||
/**
|
||||
* Set AsyncTransactionTracker of RemoveTextureFromCompositableAsync() transaction.
|
||||
*/
|
||||
virtual void SetRemoveFromCompositableTracker(AsyncTransactionTracker* aTracker) {}
|
||||
virtual void SetRemoveFromCompositableWaiter(AsyncTransactionWaiter* aWaiter) {}
|
||||
|
||||
/**
|
||||
* This function waits until the buffer is no longer being used.
|
||||
|
|
|
@ -569,10 +569,12 @@ TileClient::Flip()
|
|||
if (mFrontBuffer && mFrontBuffer->GetIPDLActor() &&
|
||||
mCompositableClient && mCompositableClient->GetIPDLActor()) {
|
||||
// remove old buffer from CompositableHost
|
||||
RefPtr<AsyncTransactionTracker> tracker = new RemoveTextureFromCompositableTracker();
|
||||
RefPtr<AsyncTransactionWaiter> waiter = new AsyncTransactionWaiter();
|
||||
RefPtr<AsyncTransactionTracker> tracker =
|
||||
new RemoveTextureFromCompositableTracker(waiter);
|
||||
// Hold TextureClient until transaction complete.
|
||||
tracker->SetTextureClient(mFrontBuffer);
|
||||
mFrontBuffer->SetRemoveFromCompositableTracker(tracker);
|
||||
mFrontBuffer->SetRemoveFromCompositableWaiter(waiter);
|
||||
// RemoveTextureFromCompositableAsync() expects CompositorChild's presence.
|
||||
mManager->AsShadowForwarder()->RemoveTextureFromCompositableAsync(tracker,
|
||||
mCompositableClient,
|
||||
|
@ -667,10 +669,12 @@ TileClient::DiscardFrontBuffer()
|
|||
if (mFrontBuffer->GetIPDLActor() &&
|
||||
mCompositableClient && mCompositableClient->GetIPDLActor()) {
|
||||
// remove old buffer from CompositableHost
|
||||
RefPtr<AsyncTransactionTracker> tracker = new RemoveTextureFromCompositableTracker();
|
||||
RefPtr<AsyncTransactionWaiter> waiter = new AsyncTransactionWaiter();
|
||||
RefPtr<AsyncTransactionTracker> tracker =
|
||||
new RemoveTextureFromCompositableTracker(waiter);
|
||||
// Hold TextureClient until transaction complete.
|
||||
tracker->SetTextureClient(mFrontBuffer);
|
||||
mFrontBuffer->SetRemoveFromCompositableTracker(tracker);
|
||||
mFrontBuffer->SetRemoveFromCompositableWaiter(waiter);
|
||||
// RemoveTextureFromCompositableAsync() expects CompositorChild's presence.
|
||||
mManager->AsShadowForwarder()->RemoveTextureFromCompositableAsync(tracker,
|
||||
mCompositableClient,
|
||||
|
|
|
@ -12,29 +12,15 @@
|
|||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
uint64_t AsyncTransactionTracker::sSerialCounter(0);
|
||||
Mutex* AsyncTransactionTracker::sLock = nullptr;
|
||||
|
||||
AsyncTransactionTracker::AsyncTransactionTracker()
|
||||
: mSerial(GetNextSerial())
|
||||
, mCompletedMonitor("AsyncTransactionTracker.mCompleted")
|
||||
, mCompleted(false)
|
||||
{
|
||||
}
|
||||
|
||||
AsyncTransactionTracker::~AsyncTransactionTracker()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AsyncTransactionTracker::WaitComplete()
|
||||
AsyncTransactionWaiter::WaitComplete()
|
||||
{
|
||||
MOZ_ASSERT(!InImageBridgeChildThread());
|
||||
|
||||
MonitorAutoLock mon(mCompletedMonitor);
|
||||
int count = 0;
|
||||
const int maxCount = 5;
|
||||
while (!mCompleted && (count < maxCount)) {
|
||||
while (mWaitCount > 0 && (count < maxCount)) {
|
||||
if (!NS_SUCCEEDED(mCompletedMonitor.Wait(PR_MillisecondsToInterval(10000)))) {
|
||||
NS_WARNING("Failed to wait Monitor");
|
||||
return;
|
||||
|
@ -45,29 +31,48 @@ AsyncTransactionTracker::WaitComplete()
|
|||
count++;
|
||||
}
|
||||
|
||||
if (!mCompleted) {
|
||||
if (mWaitCount > 0) {
|
||||
printf_stderr("Timeout of waiting transaction complete.");
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t AsyncTransactionTracker::sSerialCounter(0);
|
||||
Mutex* AsyncTransactionTracker::sLock = nullptr;
|
||||
|
||||
AsyncTransactionTracker::AsyncTransactionTracker(AsyncTransactionWaiter* aWaiter)
|
||||
: mSerial(GetNextSerial())
|
||||
, mWaiter(aWaiter)
|
||||
, mCompleted(false)
|
||||
{
|
||||
if (mWaiter) {
|
||||
mWaiter->IncrementWaitCount();
|
||||
}
|
||||
}
|
||||
|
||||
AsyncTransactionTracker::~AsyncTransactionTracker()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AsyncTransactionTracker::NotifyComplete()
|
||||
{
|
||||
MonitorAutoLock mon(mCompletedMonitor);
|
||||
MOZ_ASSERT(!mCompleted);
|
||||
mCompleted = true;
|
||||
Complete();
|
||||
mCompletedMonitor.Notify();
|
||||
if (mWaiter) {
|
||||
mWaiter->DecrementWaitCount();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AsyncTransactionTracker::NotifyCancel()
|
||||
{
|
||||
MonitorAutoLock mon(mCompletedMonitor);
|
||||
MOZ_ASSERT(!mCompleted);
|
||||
mCompleted = true;
|
||||
Cancel();
|
||||
mCompletedMonitor.Notify();
|
||||
if (mWaiter) {
|
||||
mWaiter->DecrementWaitCount();
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t AsyncTransactionTrackersHolder::sSerialCounter(0);
|
||||
|
|
|
@ -21,6 +21,46 @@ namespace layers {
|
|||
class TextureClient;
|
||||
class AsyncTransactionTrackersHolder;
|
||||
|
||||
/**
|
||||
* Object that lets you wait for one or more async transactions to complete.
|
||||
*/
|
||||
class AsyncTransactionWaiter
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncTransactionWaiter)
|
||||
|
||||
AsyncTransactionWaiter()
|
||||
: mCompletedMonitor("AsyncTransactionWaiter")
|
||||
, mWaitCount(0)
|
||||
{}
|
||||
|
||||
void IncrementWaitCount()
|
||||
{
|
||||
MonitorAutoLock lock(mCompletedMonitor);
|
||||
++mWaitCount;
|
||||
}
|
||||
void DecrementWaitCount()
|
||||
{
|
||||
MonitorAutoLock lock(mCompletedMonitor);
|
||||
MOZ_ASSERT(mWaitCount > 0);
|
||||
--mWaitCount;
|
||||
if (mWaitCount == 0) {
|
||||
mCompletedMonitor.Notify();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait until asynchronous transactions complete.
|
||||
*/
|
||||
void WaitComplete();
|
||||
|
||||
private:
|
||||
~AsyncTransactionWaiter() {}
|
||||
|
||||
Monitor mCompletedMonitor;
|
||||
uint32_t mWaitCount;
|
||||
};
|
||||
|
||||
/**
|
||||
* AsyncTransactionTracker tracks asynchronous transaction.
|
||||
* It is typically used for asynchronous layer transaction handling.
|
||||
|
@ -31,17 +71,7 @@ class AsyncTransactionTracker
|
|||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncTransactionTracker)
|
||||
|
||||
AsyncTransactionTracker();
|
||||
|
||||
Monitor& GetReentrantMonitor()
|
||||
{
|
||||
return mCompletedMonitor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait until asynchronous transaction complete.
|
||||
*/
|
||||
void WaitComplete();
|
||||
explicit AsyncTransactionTracker(AsyncTransactionWaiter* aWaiter = nullptr);
|
||||
|
||||
/**
|
||||
* Notify async transaction complete.
|
||||
|
@ -100,8 +130,8 @@ protected:
|
|||
}
|
||||
|
||||
uint64_t mSerial;
|
||||
Monitor mCompletedMonitor;
|
||||
bool mCompleted;
|
||||
RefPtr<AsyncTransactionWaiter> mWaiter;
|
||||
DebugOnly<bool> mCompleted;
|
||||
|
||||
/**
|
||||
* gecko does not provide atomic operation for uint64_t.
|
||||
|
|
|
@ -414,16 +414,21 @@ void ImageBridgeChild::DispatchImageClientUpdate(ImageClient* aClient,
|
|||
}
|
||||
|
||||
static void FlushAllImagesSync(ImageClient* aClient, ImageContainer* aContainer,
|
||||
bool aExceptFront, AsyncTransactionTracker* aStatus)
|
||||
bool aExceptFront, AsyncTransactionWaiter* aWaiter)
|
||||
{
|
||||
MOZ_ASSERT(aClient);
|
||||
sImageBridgeChildSingleton->BeginTransaction();
|
||||
if (aContainer && !aExceptFront) {
|
||||
aContainer->ClearCurrentImage();
|
||||
}
|
||||
aClient->FlushAllImages(aExceptFront, aStatus);
|
||||
aClient->FlushAllImages(aExceptFront, aWaiter);
|
||||
aClient->OnTransaction();
|
||||
sImageBridgeChildSingleton->EndTransaction();
|
||||
// This decrement is balanced by the increment in FlushAllImages.
|
||||
// If any AsyncTransactionTrackers were created by FlushAllImages and attached
|
||||
// to aWaiter, aWaiter will not complete until those trackers all complete.
|
||||
// Otherwise, aWaiter will be ready to complete now.
|
||||
aWaiter->DecrementWaitCount();
|
||||
}
|
||||
|
||||
//static
|
||||
|
@ -441,13 +446,15 @@ void ImageBridgeChild::FlushAllImages(ImageClient* aClient,
|
|||
return;
|
||||
}
|
||||
|
||||
RefPtr<AsyncTransactionTracker> status = aClient->PrepareFlushAllImages();
|
||||
RefPtr<AsyncTransactionWaiter> waiter = new AsyncTransactionWaiter();
|
||||
// This increment is balanced by the decrement in FlushAllImagesSync
|
||||
waiter->IncrementWaitCount();
|
||||
|
||||
sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(&FlushAllImagesSync, aClient, aContainer, aExceptFront, status));
|
||||
NewRunnableFunction(&FlushAllImagesSync, aClient, aContainer, aExceptFront, waiter));
|
||||
|
||||
status->WaitComplete();
|
||||
waiter->WaitComplete();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -76,17 +76,17 @@ GrallocTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
|||
}
|
||||
|
||||
void
|
||||
GrallocTextureClientOGL::SetRemoveFromCompositableTracker(AsyncTransactionTracker* aTracker)
|
||||
GrallocTextureClientOGL::SetRemoveFromCompositableWaiter(AsyncTransactionWaiter* aWaiter)
|
||||
{
|
||||
mRemoveFromCompositableTracker = aTracker;
|
||||
mRemoveFromCompositableWaiter = aWaiter;
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureClientOGL::WaitForBufferOwnership(bool aWaitReleaseFence)
|
||||
{
|
||||
if (mRemoveFromCompositableTracker) {
|
||||
mRemoveFromCompositableTracker->WaitComplete();
|
||||
mRemoveFromCompositableTracker = nullptr;
|
||||
if (mRemoveFromCompositableWaiter) {
|
||||
mRemoveFromCompositableWaiter->WaitComplete();
|
||||
mRemoveFromCompositableWaiter = nullptr;
|
||||
}
|
||||
|
||||
if (!aWaitReleaseFence) {
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual void SetRemoveFromCompositableTracker(AsyncTransactionTracker* aTracker) override;
|
||||
virtual void SetRemoveFromCompositableWaiter(AsyncTransactionWaiter* aWaiter) override;
|
||||
|
||||
virtual void WaitForBufferOwnership(bool aWaitReleaseFence = true) override;
|
||||
|
||||
|
@ -127,7 +127,7 @@ protected:
|
|||
*/
|
||||
MaybeMagicGrallocBufferHandle mGrallocHandle;
|
||||
|
||||
RefPtr<AsyncTransactionTracker> mRemoveFromCompositableTracker;
|
||||
RefPtr<AsyncTransactionWaiter> mRemoveFromCompositableWaiter;
|
||||
|
||||
android::sp<android::GraphicBuffer> mGraphicBuffer;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче