mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1252835 - Make TextureHost recycling implicit r=nical
This commit is contained in:
parent
cae8c6bcee
commit
f731d220ed
@ -306,7 +306,7 @@ SurfaceFactory::~SurfaceFactory()
|
||||
while (!mRecycleTotalPool.empty()) {
|
||||
RefPtr<layers::SharedSurfaceTextureClient> tex = *mRecycleTotalPool.begin();
|
||||
StopRecycling(tex);
|
||||
tex->CancelWaitForCompositorRecycle();
|
||||
tex->CancelWaitForRecycle();
|
||||
}
|
||||
|
||||
MOZ_RELEASE_ASSERT(mRecycleTotalPool.empty(),"GFX: Surface recycle pool not empty.");
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "mozilla/layers/CompositorBridgeParent.h" // for CompositorBridgeParent
|
||||
#include "mozilla/layers/Effects.h" // for Effect, EffectChain, etc
|
||||
#include "mozilla/layers/TextureClient.h"
|
||||
#include "mozilla/layers/TextureHost.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/mozalloc.h" // for operator delete, etc
|
||||
#include "gfx2DGlue.h"
|
||||
@ -33,6 +34,7 @@ Compositor::Compositor(widget::CompositorWidgetProxy* aWidget,
|
||||
, mPixelsFilled(0)
|
||||
, mScreenRotation(ROTATION_0)
|
||||
, mWidget(aWidget)
|
||||
, mIsDestroyed(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -44,6 +46,13 @@ Compositor::~Compositor()
|
||||
mUnlockAfterComposition.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
Compositor::Destroy()
|
||||
{
|
||||
FlushPendingNotifyNotUsed();
|
||||
mIsDestroyed = true;
|
||||
}
|
||||
|
||||
void
|
||||
Compositor::EndFrame()
|
||||
{
|
||||
@ -53,6 +62,23 @@ Compositor::EndFrame()
|
||||
mUnlockAfterComposition.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
Compositor::NotifyNotUsedAfterComposition(TextureHost* aTextureHost)
|
||||
{
|
||||
MOZ_ASSERT(!mIsDestroyed);
|
||||
|
||||
mNotifyNotUsedAfterComposition.AppendElement(aTextureHost);
|
||||
}
|
||||
|
||||
void
|
||||
Compositor::FlushPendingNotifyNotUsed()
|
||||
{
|
||||
for (auto& textureHost : mNotifyNotUsedAfterComposition) {
|
||||
textureHost->CallNotifyNotUsed();
|
||||
}
|
||||
mNotifyNotUsedAfterComposition.Clear();
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
Compositor::AssertOnCompositorThread()
|
||||
{
|
||||
|
@ -133,6 +133,7 @@ class CompositorOGL;
|
||||
class CompositorD3D9;
|
||||
class CompositorD3D11;
|
||||
class BasicCompositor;
|
||||
class TextureHost;
|
||||
class TextureReadLock;
|
||||
|
||||
enum SurfaceInitMode
|
||||
@ -200,7 +201,8 @@ public:
|
||||
CreateDataTextureSourceAround(gfx::DataSourceSurface* aSurface) { return nullptr; }
|
||||
|
||||
virtual bool Initialize() = 0;
|
||||
virtual void Destroy() = 0;
|
||||
virtual void Destroy();
|
||||
bool IsDestroyed() const { return mIsDestroyed; }
|
||||
|
||||
virtual void DetachWidget() { mWidget = nullptr; }
|
||||
|
||||
@ -544,6 +546,16 @@ public:
|
||||
mUnlockAfterComposition.AppendElement(aLock);
|
||||
}
|
||||
|
||||
/// Most compositor backends operate asynchronously under the hood. This
|
||||
/// means that when a layer stops using a texture it is often desirable to
|
||||
/// wait for the end of the next composition before NotifyNotUsed() call.
|
||||
/// This function provides a convenient way to do this delayed NotifyNotUsed()
|
||||
/// call, if the texture itself requires it.
|
||||
/// See bug 1260611 and bug 1252835
|
||||
void NotifyNotUsedAfterComposition(TextureHost* aTextureHost);
|
||||
|
||||
void FlushPendingNotifyNotUsed();
|
||||
|
||||
protected:
|
||||
void DrawDiagnosticsInternal(DiagnosticFlags aFlags,
|
||||
const gfx::Rect& aVisibleRect,
|
||||
@ -573,6 +585,11 @@ protected:
|
||||
*/
|
||||
nsTArray<RefPtr<TextureReadLock>> mUnlockAfterComposition;
|
||||
|
||||
/**
|
||||
* An array of TextureHosts that will need to call NotifyNotUsed() after the next composition.
|
||||
*/
|
||||
nsTArray<RefPtr<TextureHost>> mNotifyNotUsedAfterComposition;
|
||||
|
||||
/**
|
||||
* Render time for the current composition.
|
||||
*/
|
||||
@ -603,6 +620,8 @@ protected:
|
||||
|
||||
widget::CompositorWidgetProxy* mWidget;
|
||||
|
||||
bool mIsDestroyed;
|
||||
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
|
||||
FenceHandle mReleaseFenceHandle;
|
||||
#endif
|
||||
|
@ -44,7 +44,9 @@ enum class TextureFlags : uint32_t {
|
||||
// Data in this texture has not been alpha-premultiplied.
|
||||
// XXX - Apparently only used with ImageClient/Host
|
||||
NON_PREMULTIPLIED = 1 << 4,
|
||||
// The texture should be recycled when no longer in used
|
||||
// The TextureClient should be recycled with recycle callback when no longer
|
||||
// in used. When the texture is used in host side, ref count of TextureClient
|
||||
// is transparently added by ShadowLayerForwarder or ImageBridgeChild.
|
||||
RECYCLE = 1 << 5,
|
||||
// If DEALLOCATE_CLIENT is set, the shared data is deallocated on the
|
||||
// client side and requires some extra synchronizaion to ensure race-free
|
||||
|
@ -52,8 +52,6 @@ public:
|
||||
|
||||
virtual bool Initialize() override;
|
||||
|
||||
virtual void Destroy() override {}
|
||||
|
||||
virtual void DetachWidget() override;
|
||||
|
||||
virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() override;
|
||||
|
@ -464,25 +464,6 @@ CanvasClientSharedSurface::Updated()
|
||||
|
||||
auto forwarder = GetForwarder();
|
||||
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
if (mFront) {
|
||||
if (mFront->GetFlags() & TextureFlags::RECYCLE) {
|
||||
mFront->WaitForCompositorRecycle();
|
||||
}
|
||||
}
|
||||
#else
|
||||
// AutoRemoveTexture does the followings.
|
||||
// - Ensure to deliver FenceHandle from TextureHost to TextureClient, before
|
||||
// next TextureClient usage.
|
||||
// - Control TextureClient's recycling timing.
|
||||
// - Call RemoveTexture() after newFront's UseTextures() call.
|
||||
// It could improve performance of Host side's EGL handling on gonk
|
||||
AutoRemoveTexture autoRemove(this);
|
||||
if (mFront && mFront != mNewFront) {
|
||||
autoRemove.mTexture = mFront;
|
||||
}
|
||||
#endif
|
||||
|
||||
mFront = mNewFront;
|
||||
mNewFront = nullptr;
|
||||
|
||||
@ -505,7 +486,7 @@ CanvasClientSharedSurface::Updated()
|
||||
void
|
||||
CanvasClientSharedSurface::OnDetach() {
|
||||
if (mShSurfClient) {
|
||||
mShSurfClient->CancelWaitForCompositorRecycle();
|
||||
mShSurfClient->CancelWaitForRecycle();
|
||||
}
|
||||
ClearSurfaces();
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ ClientLayerManager::ClientLayerManager(nsIWidget* aWidget)
|
||||
, mCompositorMightResample(false)
|
||||
, mNeedsComposite(false)
|
||||
, mPaintSequenceNumber(0)
|
||||
, mForwarder(new ShadowLayerForwarder)
|
||||
, mForwarder(new ShadowLayerForwarder(this))
|
||||
, mDeviceCounter(gfxPlatform::GetPlatform()->GetDeviceCounter())
|
||||
{
|
||||
MOZ_COUNT_CTOR(ClientLayerManager);
|
||||
@ -670,7 +670,6 @@ ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
|
||||
mTransactionIdAllocator->RevokeTransactionId(mLatestTransactionId);
|
||||
}
|
||||
|
||||
mForwarder->SendPendingAsyncMessges();
|
||||
mPhase = PHASE_NONE;
|
||||
|
||||
// this may result in Layers being deleted, which results in
|
||||
|
@ -31,7 +31,6 @@ using namespace mozilla::gfx;
|
||||
* CompositableChild is owned by a CompositableClient.
|
||||
*/
|
||||
class CompositableChild : public ChildActor<PCompositableChild>
|
||||
, public AsyncTransactionTrackersHolder
|
||||
{
|
||||
public:
|
||||
CompositableChild()
|
||||
@ -46,7 +45,6 @@ public:
|
||||
}
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason) override {
|
||||
DestroyAsyncTransactionTrackersHolder();
|
||||
if (mCompositableClient) {
|
||||
mCompositableClient->mCompositableChild = nullptr;
|
||||
}
|
||||
@ -73,27 +71,6 @@ RemoveTextureFromCompositableTracker::ReleaseTextureClient()
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
CompositableClient::TransactionCompleteted(PCompositableChild* aActor, uint64_t aTransactionId)
|
||||
{
|
||||
CompositableChild* child = static_cast<CompositableChild*>(aActor);
|
||||
child->TransactionCompleteted(aTransactionId);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
CompositableClient::HoldUntilComplete(PCompositableChild* aActor, AsyncTransactionTracker* aTracker)
|
||||
{
|
||||
CompositableChild* child = static_cast<CompositableChild*>(aActor);
|
||||
child->HoldUntilComplete(aTracker);
|
||||
}
|
||||
|
||||
/* static */ uint64_t
|
||||
CompositableClient::GetTrackersHolderId(PCompositableChild* aActor)
|
||||
{
|
||||
CompositableChild* child = static_cast<CompositableChild*>(aActor);
|
||||
return child->GetId();
|
||||
}
|
||||
|
||||
/* static */ PCompositableChild*
|
||||
CompositableClient::CreateIPDLActor()
|
||||
{
|
||||
@ -181,10 +158,6 @@ CompositableClient::Destroy()
|
||||
return;
|
||||
}
|
||||
|
||||
// Send pending AsyncMessages before deleting CompositableChild since the former
|
||||
// might have references to the latter.
|
||||
mForwarder->SendPendingAsyncMessges();
|
||||
|
||||
mCompositableChild->mCompositableClient = nullptr;
|
||||
mCompositableChild->Destroy(mForwarder);
|
||||
mCompositableChild = nullptr;
|
||||
@ -299,7 +272,6 @@ CompositableClient::DumpTextureClient(std::stringstream& aStream,
|
||||
AutoRemoveTexture::~AutoRemoveTexture()
|
||||
{
|
||||
if (mCompositable && mTexture && mCompositable->IsConnected()) {
|
||||
mTexture->RemoveFromCompositable(mCompositable);
|
||||
mCompositable->RemoveTexture(mTexture);
|
||||
}
|
||||
}
|
||||
|
@ -226,12 +226,6 @@ public:
|
||||
|
||||
void InitIPDLActor(PCompositableChild* aActor, uint64_t aAsyncID = 0);
|
||||
|
||||
static void TransactionCompleteted(PCompositableChild* aActor, uint64_t aTransactionId);
|
||||
|
||||
static void HoldUntilComplete(PCompositableChild* aActor, AsyncTransactionTracker* aTracker);
|
||||
|
||||
static uint64_t GetTrackersHolderId(PCompositableChild* aActor);
|
||||
|
||||
TextureFlags GetTextureFlags() const { return mTextureFlags; }
|
||||
|
||||
TextureClientRecycleAllocator* GetTextureClientRecycler();
|
||||
|
@ -445,14 +445,6 @@ ContentClientDoubleBuffered::Updated(const nsIntRegion& aRegionToDraw,
|
||||
bool aDidSelfCopy)
|
||||
{
|
||||
ContentClientRemoteBuffer::Updated(aRegionToDraw, aVisibleRegion, aDidSelfCopy);
|
||||
|
||||
if (mFrontClient) {
|
||||
mFrontClient->RemoveFromCompositable(this);
|
||||
}
|
||||
|
||||
if (mFrontClientOnWhite) {
|
||||
mFrontClientOnWhite->RemoveFromCompositable(this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -77,23 +77,14 @@ void
|
||||
ImageClient::RemoveTextureWithWaiter(TextureClient* aTexture,
|
||||
AsyncTransactionWaiter* aAsyncTransactionWaiter)
|
||||
{
|
||||
if ((aAsyncTransactionWaiter || GetForwarder()->UsesImageBridge())
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
// If the texture client is taking part in recycling then we should make sure
|
||||
// the host has finished with it before dropping the ref and triggering
|
||||
// the recycle callback.
|
||||
&& aTexture->GetRecycleAllocator()
|
||||
#endif
|
||||
) {
|
||||
if (aAsyncTransactionWaiter &&
|
||||
GetForwarder()->UsesImageBridge()) {
|
||||
RefPtr<AsyncTransactionTracker> request =
|
||||
new RemoveTextureFromCompositableTracker(aAsyncTransactionWaiter);
|
||||
// Hold TextureClient until the transaction complete to postpone
|
||||
// the TextureClient recycle/delete.
|
||||
request->SetTextureClient(aTexture);
|
||||
GetForwarder()->RemoveTextureFromCompositableAsync(request, this, aTexture);
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!aAsyncTransactionWaiter);
|
||||
GetForwarder()->RemoveTextureFromCompositable(this, aTexture);
|
||||
}
|
||||
|
||||
@ -112,6 +103,8 @@ TextureInfo ImageClientSingle::GetTextureInfo() const
|
||||
void
|
||||
ImageClientSingle::FlushAllImages(AsyncTransactionWaiter* aAsyncTransactionWaiter)
|
||||
{
|
||||
MOZ_ASSERT(GetForwarder()->UsesImageBridge());
|
||||
|
||||
for (auto& b : mBuffers) {
|
||||
RemoveTextureWithWaiter(b.mTextureClient, aAsyncTransactionWaiter);
|
||||
}
|
||||
|
@ -13,8 +13,10 @@
|
||||
#include "mozilla/layers/AsyncTransactionTracker.h"
|
||||
#include "mozilla/layers/CompositableForwarder.h"
|
||||
#include "mozilla/layers/ISurfaceAllocator.h"
|
||||
#include "mozilla/layers/ImageBridgeChild.h"
|
||||
#include "mozilla/layers/ImageDataSerializer.h"
|
||||
#include "mozilla/layers/TextureClientRecycleAllocator.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsDebug.h" // for NS_ASSERTION, NS_WARNING, etc
|
||||
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
|
||||
#include "ImageContainer.h" // for PlanarYCbCrData, etc
|
||||
@ -108,33 +110,6 @@ public:
|
||||
|
||||
bool Recv__delete__() override { return true; }
|
||||
|
||||
bool RecvCompositorRecycle() override
|
||||
{
|
||||
RECYCLE_LOG("[CLIENT] Receive recycle %p (%p)\n", mTextureClient, mWaitForRecycle.get());
|
||||
mWaitForRecycle = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
void WaitForCompositorRecycle()
|
||||
{
|
||||
Lock();
|
||||
mWaitForRecycle = mDestroyed ? nullptr : mTextureClient;
|
||||
Unlock();
|
||||
|
||||
RECYCLE_LOG("[CLIENT] Wait for recycle %p\n", mWaitForRecycle.get());
|
||||
MOZ_ASSERT(CanSend());
|
||||
SendClientRecycle();
|
||||
}
|
||||
|
||||
void CancelWaitForCompositorRecycle()
|
||||
{
|
||||
RECYCLE_LOG("[CLIENT] Cancelling wait for recycle %p\n", mWaitForRecycle.get());
|
||||
|
||||
Lock();
|
||||
mWaitForRecycle = nullptr;
|
||||
Unlock();
|
||||
}
|
||||
|
||||
CompositableForwarder* GetForwarder() { return mForwarder; }
|
||||
|
||||
ClientIPCAllocator* GetAllocator() { return mForwarder; }
|
||||
@ -230,7 +205,6 @@ private:
|
||||
mutable gfx::CriticalSection mLock;
|
||||
|
||||
RefPtr<CompositableForwarder> mForwarder;
|
||||
RefPtr<TextureClient> mWaitForRecycle;
|
||||
|
||||
TextureClient* mTextureClient;
|
||||
TextureData* mTextureData;
|
||||
@ -271,7 +245,6 @@ void
|
||||
TextureChild::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
PROFILER_LABEL_FUNC(js::ProfileEntry::Category::GRAPHICS);
|
||||
mWaitForRecycle = nullptr;
|
||||
|
||||
if (mTextureData) {
|
||||
DestroyTextureData(mTextureData, GetAllocator(), mOwnsTextureData, mMainThreadOnly);
|
||||
@ -279,6 +252,8 @@ TextureChild::ActorDestroy(ActorDestroyReason why)
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ Atomic<uint64_t> TextureClient::sSerialCounter(0);
|
||||
|
||||
void DeallocateTextureClientSyncProxy(TextureDeallocParams params,
|
||||
ReentrantMonitor* aBarrier, bool* aDone)
|
||||
{
|
||||
@ -385,6 +360,7 @@ void TextureClient::Destroy(bool aForceSync)
|
||||
mActor->Lock();
|
||||
}
|
||||
|
||||
CancelWaitFenceHandleOnImageBridge();
|
||||
RefPtr<TextureChild> actor = mActor;
|
||||
mActor = nullptr;
|
||||
|
||||
@ -464,9 +440,8 @@ TextureClient::Lock(OpenMode aMode)
|
||||
return mOpenMode == aMode;
|
||||
}
|
||||
|
||||
if (mRemoveFromCompositableWaiter) {
|
||||
mRemoveFromCompositableWaiter->WaitComplete();
|
||||
mRemoveFromCompositableWaiter = nullptr;
|
||||
if (!!mFenceHandleWaiter && (aMode & OpenMode::OPEN_WRITE)) {
|
||||
mFenceHandleWaiter->WaitComplete();
|
||||
}
|
||||
|
||||
if (aMode & OpenMode::OPEN_WRITE && IsReadLocked()) {
|
||||
@ -476,7 +451,8 @@ TextureClient::Lock(OpenMode aMode)
|
||||
|
||||
LockActor();
|
||||
|
||||
mIsLocked = mData->Lock(aMode, mReleaseFenceHandle.IsValid() ? &mReleaseFenceHandle : nullptr);
|
||||
FenceHandle* fence = (mReleaseFenceHandle.IsValid() && (aMode & OpenMode::OPEN_WRITE)) ? &mReleaseFenceHandle : nullptr;
|
||||
mIsLocked = mData->Lock(aMode, fence);
|
||||
mOpenMode = aMode;
|
||||
|
||||
auto format = GetFormat();
|
||||
@ -683,9 +659,8 @@ TextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
||||
void
|
||||
TextureClient::WaitForBufferOwnership(bool aWaitReleaseFence)
|
||||
{
|
||||
if (mRemoveFromCompositableWaiter) {
|
||||
mRemoveFromCompositableWaiter->WaitComplete();
|
||||
mRemoveFromCompositableWaiter = nullptr;
|
||||
if (mFenceHandleWaiter) {
|
||||
mFenceHandleWaiter->WaitComplete();
|
||||
}
|
||||
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION < 21
|
||||
@ -788,22 +763,6 @@ TextureClient::RecycleTexture(TextureFlags aFlags)
|
||||
UnlockActor();
|
||||
}
|
||||
|
||||
void
|
||||
TextureClient::WaitForCompositorRecycle()
|
||||
{
|
||||
if (IsSharedWithCompositor()) {
|
||||
mActor->WaitForCompositorRecycle();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextureClient::CancelWaitForCompositorRecycle()
|
||||
{
|
||||
if (IsSharedWithCompositor()) {
|
||||
mActor->CancelWaitForCompositorRecycle();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextureClient::SetAddedToCompositableClient()
|
||||
{
|
||||
@ -812,6 +771,75 @@ TextureClient::SetAddedToCompositableClient()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextureClient::WaitFenceHandleOnImageBridge(Mutex& aMutex)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
aMutex.AssertCurrentThreadOwns();
|
||||
|
||||
if (!mFenceHandleWaiter) {
|
||||
mFenceHandleWaiter = new AsyncTransactionWaiter();
|
||||
}
|
||||
MOZ_ASSERT(mFenceHandleWaiter->GetWaitCount() <= 1);
|
||||
if (mFenceHandleWaiter->GetWaitCount() > 0) {
|
||||
return;
|
||||
}
|
||||
mFenceHandleWaiter->IncrementWaitCount();
|
||||
}
|
||||
|
||||
void
|
||||
TextureClient::ClearWaitFenceHandleOnImageBridge(Mutex& aMutex)
|
||||
{
|
||||
MOZ_ASSERT(InImageBridgeChildThread());
|
||||
aMutex.AssertCurrentThreadOwns();
|
||||
|
||||
if (!mFenceHandleWaiter) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(mFenceHandleWaiter->GetWaitCount() <= 1);
|
||||
if (mFenceHandleWaiter->GetWaitCount() == 0) {
|
||||
return;
|
||||
}
|
||||
mFenceHandleWaiter->DecrementWaitCount();
|
||||
}
|
||||
|
||||
void
|
||||
TextureClient::CancelWaitFenceHandleOnImageBridge()
|
||||
{
|
||||
if (!NeedsFenceHandle() || GetFlags() & TextureFlags::RECYCLE) {
|
||||
return;
|
||||
}
|
||||
ImageBridgeChild::GetSingleton()->CancelWaitFenceHandle(this);
|
||||
}
|
||||
|
||||
void CancelTextureClientRecycle(uint64_t aTextureId, ClientIPCAllocator* aAllocator)
|
||||
{
|
||||
if (!aAllocator) {
|
||||
return;
|
||||
}
|
||||
MessageLoop* msgLoop = nullptr;
|
||||
msgLoop = aAllocator->GetMessageLoop();
|
||||
if (!msgLoop) {
|
||||
return;
|
||||
}
|
||||
if (MessageLoop::current() == msgLoop) {
|
||||
aAllocator->CancelWaitForRecycle(aTextureId);
|
||||
} else {
|
||||
msgLoop->PostTask(NewRunnableFunction(CancelTextureClientRecycle,
|
||||
aTextureId, aAllocator));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextureClient::CancelWaitForRecycle()
|
||||
{
|
||||
if (GetFlags() & TextureFlags::RECYCLE) {
|
||||
CancelTextureClientRecycle(mSerial, GetAllocator());
|
||||
return;
|
||||
}
|
||||
CancelWaitFenceHandleOnImageBridge();
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
TextureClient::TextureClientRecycleCallback(TextureClient* aClient, void* aClosure)
|
||||
{
|
||||
@ -844,7 +872,10 @@ TextureClient::InitIPDLActor(CompositableForwarder* aForwarder)
|
||||
return false;
|
||||
}
|
||||
|
||||
mActor = static_cast<TextureChild*>(aForwarder->CreateTexture(desc, aForwarder->GetCompositorBackendType(), GetFlags()));
|
||||
mActor = static_cast<TextureChild*>(aForwarder->CreateTexture(desc,
|
||||
aForwarder->GetCompositorBackendType(),
|
||||
GetFlags(),
|
||||
mSerial));
|
||||
MOZ_ASSERT(mActor);
|
||||
mActor->mForwarder = aForwarder;
|
||||
mActor->mTextureClient = this;
|
||||
@ -1072,10 +1103,11 @@ TextureClient::TextureClient(TextureData* aData, TextureFlags aFlags, ClientIPCA
|
||||
#endif
|
||||
, mIsLocked(false)
|
||||
, mUpdated(false)
|
||||
, mInUse(false)
|
||||
, mAddedToCompositableClient(false)
|
||||
, mWorkaroundAnnoyingSharedSurfaceLifetimeIssues(false)
|
||||
, mWorkaroundAnnoyingSharedSurfaceOwnershipIssues(false)
|
||||
, mFwdTransactionId(0)
|
||||
, mSerial(++sSerialCounter)
|
||||
#ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL
|
||||
, mPoolTracker(nullptr)
|
||||
#endif
|
||||
@ -1114,35 +1146,6 @@ bool TextureClient::CopyToTextureClient(TextureClient* aTarget,
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TextureClient::RemoveFromCompositable(CompositableClient* aCompositable,
|
||||
AsyncTransactionWaiter* aWaiter)
|
||||
{
|
||||
MOZ_ASSERT(aCompositable);
|
||||
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
|
||||
if (mActor && aCompositable->GetIPDLActor()
|
||||
&& mData->AsGrallocTextureData()) {
|
||||
// remove old buffer from CompositableHost
|
||||
RefPtr<AsyncTransactionWaiter> waiter = aWaiter ? aWaiter
|
||||
: new AsyncTransactionWaiter();
|
||||
RefPtr<AsyncTransactionTracker> tracker =
|
||||
new RemoveTextureFromCompositableTracker(waiter);
|
||||
// Hold TextureClient until transaction complete.
|
||||
tracker->SetTextureClient(this);
|
||||
mRemoveFromCompositableWaiter = waiter;
|
||||
// RemoveTextureFromCompositableAsync() expects CompositorBridgeChild's presence.
|
||||
mActor->GetForwarder()->RemoveTextureFromCompositableAsync(tracker, aCompositable, this);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
TextureClient::SetRemoveFromCompositableWaiter(AsyncTransactionWaiter* aWaiter) {
|
||||
mRemoveFromCompositableWaiter = aWaiter;
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface>
|
||||
TextureClient::GetAsSurface()
|
||||
{
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "nsISupportsImpl.h" // for TextureImage::AddRef, etc
|
||||
#include "GfxTexturesReporter.h"
|
||||
#include "pratom.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
class gfxImageSurface;
|
||||
|
||||
@ -410,13 +411,6 @@ public:
|
||||
|
||||
bool CanExposeMappedData() const { return mInfo.canExposeMappedData; }
|
||||
|
||||
/* TextureClientRecycleAllocator tracking to decide if we need
|
||||
* to check with the compositor before recycling.
|
||||
* Should be superceeded (and removed) by bug 1252835.
|
||||
*/
|
||||
void SetInUse(bool aInUse) { mInUse = aInUse; }
|
||||
bool IsInUse() { return mInUse; }
|
||||
|
||||
/**
|
||||
* Returns a DrawTarget to draw into the TextureClient.
|
||||
* This function should never be called when not on the main thread!
|
||||
@ -513,21 +507,6 @@ public:
|
||||
// The TextureClient must not be locked when calling this method.
|
||||
void RecycleTexture(TextureFlags aFlags);
|
||||
|
||||
/**
|
||||
* valid only for TextureFlags::RECYCLE TextureClient.
|
||||
* When called this texture client will grab a strong reference and release
|
||||
* it once the compositor notifies that it is done with the texture.
|
||||
* NOTE: In this stage the texture client can no longer be used by the
|
||||
* client in a transaction.
|
||||
*/
|
||||
void WaitForCompositorRecycle();
|
||||
|
||||
/**
|
||||
* Should only be called when dying. We no longer care whether the compositor
|
||||
* has finished with the texture.
|
||||
*/
|
||||
void CancelWaitForCompositorRecycle();
|
||||
|
||||
/**
|
||||
* After being shared with the compositor side, an immutable texture is never
|
||||
* modified, it can only be read. It is safe to not Lock/Unlock immutable
|
||||
@ -605,11 +584,6 @@ public:
|
||||
return mAcquireFenceHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set AsyncTransactionTracker of RemoveTextureFromCompositableAsync() transaction.
|
||||
*/
|
||||
virtual void SetRemoveFromCompositableWaiter(AsyncTransactionWaiter* aWaiter);
|
||||
|
||||
/**
|
||||
* This function waits until the buffer is no longer being used.
|
||||
*
|
||||
@ -646,9 +620,43 @@ public:
|
||||
TextureData* GetInternalData() { return mData; }
|
||||
const TextureData* GetInternalData() const { return mData; }
|
||||
|
||||
virtual void RemoveFromCompositable(CompositableClient* aCompositable,
|
||||
AsyncTransactionWaiter* aWaiter = nullptr);
|
||||
uint64_t GetSerial() const { return mSerial; }
|
||||
|
||||
bool NeedsFenceHandle()
|
||||
{
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
|
||||
if (!mData) {
|
||||
return false;
|
||||
}
|
||||
return !!mData->AsGrallocTextureData();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void WaitFenceHandleOnImageBridge(Mutex& aMutex);
|
||||
void ClearWaitFenceHandleOnImageBridge(Mutex& aMutex);
|
||||
void CancelWaitFenceHandleOnImageBridge();
|
||||
|
||||
void CancelWaitForRecycle();
|
||||
|
||||
/**
|
||||
* Set last transaction id of CompositableForwarder.
|
||||
*
|
||||
* Called when TextureClient has TextureFlags::RECYCLE flag.
|
||||
* When CompositableForwarder forwards the TextureClient with
|
||||
* TextureFlags::RECYCLE, it holds TextureClient's ref until host side
|
||||
* releases it. The host side sends TextureClient release message.
|
||||
* The id is used to check if the message is for the last TextureClient
|
||||
* forwarding.
|
||||
*/
|
||||
void SetLastFwdTransactionId(uint64_t aTransactionId)
|
||||
{
|
||||
MOZ_ASSERT(mFwdTransactionId < aTransactionId);
|
||||
mFwdTransactionId = aTransactionId;
|
||||
}
|
||||
|
||||
uint64_t GetLastFwdTransactionId() { return mFwdTransactionId; }
|
||||
|
||||
void EnableReadLock();
|
||||
|
||||
@ -691,7 +699,6 @@ protected:
|
||||
RefPtr<ClientIPCAllocator> mAllocator;
|
||||
RefPtr<TextureChild> mActor;
|
||||
RefPtr<ITextureClientRecycleAllocator> mRecycleAllocator;
|
||||
RefPtr<AsyncTransactionWaiter> mRemoveFromCompositableWaiter;
|
||||
RefPtr<TextureReadLock> mReadLock;
|
||||
|
||||
TextureData* mData;
|
||||
@ -700,6 +707,8 @@ protected:
|
||||
TextureFlags mFlags;
|
||||
FenceHandle mReleaseFenceHandle;
|
||||
FenceHandle mAcquireFenceHandle;
|
||||
RefPtr<AsyncTransactionWaiter> mFenceHandleWaiter;
|
||||
|
||||
gl::GfxTextureWasteTracker mWasteTracker;
|
||||
|
||||
OpenMode mOpenMode;
|
||||
@ -711,7 +720,6 @@ protected:
|
||||
// is sent to the compositor. We need this remember to lock mReadLock on
|
||||
// behalf of the compositor just before sending the notification.
|
||||
bool mUpdated;
|
||||
bool mInUse;
|
||||
|
||||
bool mAddedToCompositableClient;
|
||||
bool mWorkaroundAnnoyingSharedSurfaceLifetimeIssues;
|
||||
@ -719,6 +727,13 @@ protected:
|
||||
|
||||
RefPtr<TextureReadbackSink> mReadbackSink;
|
||||
|
||||
uint64_t mFwdTransactionId;
|
||||
|
||||
// Serial id of TextureClient. It is unique in current process.
|
||||
const uint64_t mSerial;
|
||||
// Used to assign serial ids of TextureClient.
|
||||
static mozilla::Atomic<uint64_t> sSerialCounter;
|
||||
|
||||
friend class TextureChild;
|
||||
friend class RemoveTextureFromCompositableTracker;
|
||||
friend void TestTextureClientSurface(TextureClient*, gfxImageSurface*);
|
||||
|
@ -181,7 +181,6 @@ TextureClientRecycleAllocator::CreateOrRecycle(ITextureClientAllocationHelper& a
|
||||
// Make sure the texture holds a reference to us, and ask it to call RecycleTextureClient when its
|
||||
// ref count drops to 1.
|
||||
client->SetRecycleAllocator(this);
|
||||
client->SetInUse(true);
|
||||
return client.forget();
|
||||
}
|
||||
|
||||
@ -205,35 +204,9 @@ TextureClientRecycleAllocator::ShrinkToMinimumSize()
|
||||
}
|
||||
}
|
||||
|
||||
class TextureClientWaitTask : public Runnable
|
||||
{
|
||||
public:
|
||||
explicit TextureClientWaitTask(TextureClient* aClient)
|
||||
: mTextureClient(aClient)
|
||||
{}
|
||||
|
||||
NS_IMETHOD Run() override
|
||||
{
|
||||
mTextureClient->WaitForCompositorRecycle();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<TextureClient> mTextureClient;
|
||||
};
|
||||
|
||||
void
|
||||
TextureClientRecycleAllocator::RecycleTextureClient(TextureClient* aClient)
|
||||
{
|
||||
if (aClient->IsInUse()) {
|
||||
aClient->SetInUse(false);
|
||||
// This adds another ref to aClient, and drops it after a round trip
|
||||
// to the compositor. We should then get this callback a second time
|
||||
// and can recycle properly.
|
||||
RefPtr<Runnable> task = new TextureClientWaitTask(aClient);
|
||||
mSurfaceAllocator->GetMessageLoop()->PostTask(task.forget());
|
||||
return;
|
||||
}
|
||||
// Clearing the recycle allocator drops a reference, so make sure we stay alive
|
||||
// for the duration of this function.
|
||||
RefPtr<TextureClientRecycleAllocator> kungFuDeathGrip(this);
|
||||
|
@ -470,15 +470,6 @@ TileClient::Dump(std::stringstream& aStream)
|
||||
void
|
||||
TileClient::Flip()
|
||||
{
|
||||
if (mCompositableClient) {
|
||||
if (mFrontBuffer) {
|
||||
mFrontBuffer->RemoveFromCompositable(mCompositableClient);
|
||||
}
|
||||
if (mFrontBufferOnWhite) {
|
||||
mFrontBufferOnWhite->RemoveFromCompositable(mCompositableClient);
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<TextureClient> frontBuffer = mFrontBuffer;
|
||||
RefPtr<TextureClient> frontBufferOnWhite = mFrontBufferOnWhite;
|
||||
mFrontBuffer = mBackBuffer;
|
||||
@ -559,13 +550,8 @@ TileClient::DiscardFrontBuffer()
|
||||
if (mFrontBuffer) {
|
||||
MOZ_ASSERT(mFrontBuffer->GetReadLock());
|
||||
|
||||
if (mCompositableClient) {
|
||||
mFrontBuffer->RemoveFromCompositable(mCompositableClient);
|
||||
}
|
||||
|
||||
mAllocator->ReturnTextureClientDeferred(mFrontBuffer);
|
||||
if (mFrontBufferOnWhite) {
|
||||
mFrontBufferOnWhite->RemoveFromCompositable(mCompositableClient);
|
||||
mAllocator->ReturnTextureClientDeferred(mFrontBufferOnWhite);
|
||||
}
|
||||
if (mFrontBuffer->IsLocked()) {
|
||||
|
@ -188,7 +188,7 @@ public:
|
||||
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) = 0;
|
||||
|
||||
struct TimedTexture {
|
||||
RefPtr<TextureHost> mTexture;
|
||||
CompositableTextureHostRef mTexture;
|
||||
TimeStamp mTimeStamp;
|
||||
gfx::IntRect mPictureRect;
|
||||
int32_t mFrameID;
|
||||
|
@ -331,11 +331,6 @@ ImageHost::Composite(LayerComposite* aLayer,
|
||||
|
||||
TimedImage* img = &mImages[imageIndex];
|
||||
img->mTextureHost->SetCompositor(GetCompositor());
|
||||
// If this TextureHost will be recycled, then make sure we hold a reference to
|
||||
// it until we're sure that the compositor has finished reading from it.
|
||||
if (img->mTextureHost->GetFlags() & TextureFlags::RECYCLE) {
|
||||
aLayer->GetLayerManager()->HoldTextureUntilNextComposite(img->mTextureHost);
|
||||
}
|
||||
SetCurrentTextureHost(img->mTextureHost);
|
||||
|
||||
{
|
||||
|
@ -395,9 +395,7 @@ LayerManagerComposite::EndTransaction(const TimeStamp& aTimeStamp,
|
||||
if (mRoot && !(aFlags & END_NO_IMMEDIATE_REDRAW)) {
|
||||
MOZ_ASSERT(!aTimeStamp.IsNull());
|
||||
UpdateAndRender();
|
||||
|
||||
mPreviousHeldTextureHosts.Clear();
|
||||
mPreviousHeldTextureHosts.SwapElements(mCurrentHeldTextureHosts);
|
||||
mCompositor->FlushPendingNotifyNotUsed();
|
||||
} else {
|
||||
// Modified the layer tree.
|
||||
mGeometryChanged = true;
|
||||
|
@ -337,10 +337,6 @@ public:
|
||||
|
||||
void ForcePresent() { mCompositor->ForcePresent(); }
|
||||
|
||||
void HoldTextureUntilNextComposite(TextureHost* aTextureHost) {
|
||||
mCurrentHeldTextureHosts.AppendElement(aTextureHost);
|
||||
}
|
||||
|
||||
private:
|
||||
/** Region we're clipping our current drawing to. */
|
||||
nsIntRegion mClippingRegion;
|
||||
@ -401,9 +397,6 @@ private:
|
||||
|
||||
nsTArray<ImageCompositeNotification> mImageCompositeNotifications;
|
||||
|
||||
nsTArray<RefPtr<TextureHost>> mCurrentHeldTextureHosts;
|
||||
nsTArray<RefPtr<TextureHost>> mPreviousHeldTextureHosts;
|
||||
|
||||
/**
|
||||
* Context target, nullptr when drawing directly to our swap chain.
|
||||
*/
|
||||
|
@ -66,7 +66,7 @@ namespace layers {
|
||||
class TextureParent : public ParentActor<PTextureParent>
|
||||
{
|
||||
public:
|
||||
explicit TextureParent(HostIPCAllocator* aAllocator);
|
||||
explicit TextureParent(HostIPCAllocator* aAllocator, uint64_t aSerial);
|
||||
|
||||
~TextureParent();
|
||||
|
||||
@ -74,9 +74,7 @@ public:
|
||||
const LayersBackend& aLayersBackend,
|
||||
const TextureFlags& aFlags);
|
||||
|
||||
void CompositorRecycle();
|
||||
|
||||
virtual bool RecvClientRecycle() override;
|
||||
void NotifyNotUsed(uint64_t aTransactionId);
|
||||
|
||||
virtual bool RecvRecycleTexture(const TextureFlags& aTextureFlags) override;
|
||||
|
||||
@ -84,9 +82,12 @@ public:
|
||||
|
||||
virtual void Destroy() override;
|
||||
|
||||
uint64_t GetSerial() const { return mSerial; }
|
||||
|
||||
HostIPCAllocator* mSurfaceAllocator;
|
||||
RefPtr<TextureHost> mWaitForClientRecycle;
|
||||
RefPtr<TextureHost> mTextureHost;
|
||||
// mSerial is unique in TextureClient's process.
|
||||
const uint64_t mSerial;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -94,7 +95,8 @@ PTextureParent*
|
||||
TextureHost::CreateIPDLActor(HostIPCAllocator* aAllocator,
|
||||
const SurfaceDescriptor& aSharedData,
|
||||
LayersBackend aLayersBackend,
|
||||
TextureFlags aFlags)
|
||||
TextureFlags aFlags,
|
||||
uint64_t aSerial)
|
||||
{
|
||||
if (aSharedData.type() == SurfaceDescriptor::TSurfaceDescriptorBuffer &&
|
||||
aSharedData.get_SurfaceDescriptorBuffer().data().type() == MemoryOrShmem::Tuintptr_t &&
|
||||
@ -103,7 +105,7 @@ TextureHost::CreateIPDLActor(HostIPCAllocator* aAllocator,
|
||||
NS_ERROR("A client process is trying to peek at our address space using a MemoryTexture!");
|
||||
return nullptr;
|
||||
}
|
||||
TextureParent* actor = new TextureParent(aAllocator);
|
||||
TextureParent* actor = new TextureParent(aAllocator, aSerial);
|
||||
if (!actor->Init(aSharedData, aLayersBackend, aFlags)) {
|
||||
delete actor;
|
||||
return nullptr;
|
||||
@ -136,6 +138,16 @@ TextureHost::AsTextureHost(PTextureParent* actor)
|
||||
return static_cast<TextureParent*>(actor)->mTextureHost;
|
||||
}
|
||||
|
||||
// static
|
||||
uint64_t
|
||||
TextureHost::GetTextureSerial(PTextureParent* actor)
|
||||
{
|
||||
if (!actor) {
|
||||
return UINT64_MAX;
|
||||
}
|
||||
return static_cast<TextureParent*>(actor)->mSerial;
|
||||
}
|
||||
|
||||
PTextureParent*
|
||||
TextureHost::GetIPDLActor()
|
||||
{
|
||||
@ -177,6 +189,13 @@ TextureHost::GetAndResetAcquireFenceHandle()
|
||||
return FenceHandle(fdObj);
|
||||
}
|
||||
|
||||
void
|
||||
TextureHost::SetLastFwdTransactionId(uint64_t aTransactionId)
|
||||
{
|
||||
MOZ_ASSERT(mFwdTransactionId <= aTransactionId);
|
||||
mFwdTransactionId = aTransactionId;
|
||||
}
|
||||
|
||||
// implemented in TextureHostOGL.cpp
|
||||
already_AddRefed<TextureHost> CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
|
||||
ISurfaceAllocator* aDeallocator,
|
||||
@ -293,19 +312,11 @@ CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc,
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
void
|
||||
TextureHost::CompositorRecycle()
|
||||
{
|
||||
if (!mActor) {
|
||||
return;
|
||||
}
|
||||
static_cast<TextureParent*>(mActor)->CompositorRecycle();
|
||||
}
|
||||
|
||||
TextureHost::TextureHost(TextureFlags aFlags)
|
||||
: mActor(nullptr)
|
||||
, mFlags(aFlags)
|
||||
, mCompositableCount(0)
|
||||
, mFwdTransactionId(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(TextureHost);
|
||||
}
|
||||
@ -353,10 +364,51 @@ TextureHost::RecycleTexture(TextureFlags aFlags)
|
||||
{
|
||||
MOZ_ASSERT(GetFlags() & TextureFlags::RECYCLE);
|
||||
MOZ_ASSERT(aFlags & TextureFlags::RECYCLE);
|
||||
MOZ_ASSERT(!HasRecycleCallback());
|
||||
mFlags = aFlags;
|
||||
}
|
||||
|
||||
void
|
||||
TextureHost::NotifyNotUsed()
|
||||
{
|
||||
if (!mActor) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not need to call NotifyNotUsed() if TextureHost does not have
|
||||
// TextureFlags::RECYCLE flag and TextureHost is not GrallocTextureHostOGL.
|
||||
if (!(GetFlags() & TextureFlags::RECYCLE) &&
|
||||
!AsGrallocTextureHostOGL()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto compositor = GetCompositor();
|
||||
// The following cases do not need to defer NotifyNotUsed until next Composite.
|
||||
// - TextureHost does not have Compositor.
|
||||
// - Compositor is BasicCompositor.
|
||||
// - TextureHost has intermediate buffer.
|
||||
// - TextureHost is GrallocTextureHostOGL. Fence object is used to detect
|
||||
// end of buffer usage.
|
||||
if (!compositor ||
|
||||
compositor->IsDestroyed() ||
|
||||
compositor->AsBasicCompositor() ||
|
||||
HasIntermediateBuffer() ||
|
||||
AsGrallocTextureHostOGL()) {
|
||||
static_cast<TextureParent*>(mActor)->NotifyNotUsed(mFwdTransactionId);
|
||||
return;
|
||||
}
|
||||
|
||||
compositor->NotifyNotUsedAfterComposition(this);
|
||||
}
|
||||
|
||||
void
|
||||
TextureHost::CallNotifyNotUsed()
|
||||
{
|
||||
if (!mActor) {
|
||||
return;
|
||||
}
|
||||
static_cast<TextureParent*>(mActor)->NotifyNotUsed(mFwdTransactionId);
|
||||
}
|
||||
|
||||
void
|
||||
TextureHost::PrintInfo(std::stringstream& aStream, const char* aPrefix)
|
||||
{
|
||||
@ -964,8 +1016,9 @@ size_t MemoryTextureHost::GetBufferSize()
|
||||
return std::numeric_limits<size_t>::max();
|
||||
}
|
||||
|
||||
TextureParent::TextureParent(HostIPCAllocator* aSurfaceAllocator)
|
||||
TextureParent::TextureParent(HostIPCAllocator* aSurfaceAllocator, uint64_t aSerial)
|
||||
: mSurfaceAllocator(aSurfaceAllocator)
|
||||
, mSerial(aSerial)
|
||||
{
|
||||
MOZ_COUNT_CTOR(TextureParent);
|
||||
}
|
||||
@ -973,40 +1026,15 @@ TextureParent::TextureParent(HostIPCAllocator* aSurfaceAllocator)
|
||||
TextureParent::~TextureParent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(TextureParent);
|
||||
if (mTextureHost) {
|
||||
mTextureHost->ClearRecycleCallback();
|
||||
}
|
||||
}
|
||||
|
||||
static void RecycleCallback(TextureHost*, void* aClosure) {
|
||||
TextureParent* tp = reinterpret_cast<TextureParent*>(aClosure);
|
||||
tp->CompositorRecycle();
|
||||
}
|
||||
|
||||
void
|
||||
TextureParent::CompositorRecycle()
|
||||
TextureParent::NotifyNotUsed(uint64_t aTransactionId)
|
||||
{
|
||||
mTextureHost->ClearRecycleCallback();
|
||||
|
||||
if (mTextureHost->GetFlags() & TextureFlags::RECYCLE) {
|
||||
mozilla::Unused << SendCompositorRecycle();
|
||||
// Don't forget to prepare for the next reycle
|
||||
// if TextureClient request it.
|
||||
mWaitForClientRecycle = mTextureHost;
|
||||
if (!mTextureHost) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TextureParent::RecvClientRecycle()
|
||||
{
|
||||
// This will allow the RecycleCallback to be called once the compositor
|
||||
// releases any external references to TextureHost.
|
||||
mTextureHost->SetRecycleCallback(RecycleCallback, this);
|
||||
if (!mWaitForClientRecycle) {
|
||||
RECYCLE_LOG("Not a recycable tile");
|
||||
}
|
||||
mWaitForClientRecycle = nullptr;
|
||||
return true;
|
||||
mSurfaceAllocator->NotifyNotUsed(this, aTransactionId);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1020,10 +1048,6 @@ TextureParent::Init(const SurfaceDescriptor& aSharedData,
|
||||
aFlags);
|
||||
if (mTextureHost) {
|
||||
mTextureHost->mActor = this;
|
||||
if (aFlags & TextureFlags::RECYCLE) {
|
||||
mWaitForClientRecycle = mTextureHost;
|
||||
RECYCLE_LOG("Setup recycling for tile %p\n", this);
|
||||
}
|
||||
}
|
||||
|
||||
return !!mTextureHost;
|
||||
@ -1036,18 +1060,10 @@ TextureParent::Destroy()
|
||||
return;
|
||||
}
|
||||
|
||||
if (mTextureHost->GetFlags() & TextureFlags::RECYCLE) {
|
||||
RECYCLE_LOG("clear recycling for tile %p\n", this);
|
||||
mTextureHost->ClearRecycleCallback();
|
||||
}
|
||||
if (mTextureHost->GetFlags() & TextureFlags::DEALLOCATE_CLIENT) {
|
||||
mTextureHost->ForgetSharedData();
|
||||
}
|
||||
|
||||
// Clear recycle callback.
|
||||
mTextureHost->ClearRecycleCallback();
|
||||
mWaitForClientRecycle = nullptr;
|
||||
|
||||
mTextureHost->mActor = nullptr;
|
||||
mTextureHost = nullptr;
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ class Compositor;
|
||||
class CompositableParentManager;
|
||||
class ReadLockDescriptor;
|
||||
class CompositorBridgeParent;
|
||||
class GrallocTextureHostOGL;
|
||||
class SurfaceDescriptor;
|
||||
class HostIPCAllocator;
|
||||
class ISurfaceAllocator;
|
||||
@ -384,16 +385,6 @@ public:
|
||||
LayersBackend aBackend,
|
||||
TextureFlags aFlags);
|
||||
|
||||
/**
|
||||
* Tell to TextureChild that TextureHost is recycled.
|
||||
* This function should be called from TextureHost's RecycleCallback.
|
||||
* If SetRecycleCallback is set to TextureHost.
|
||||
* TextureHost can be recycled by calling RecycleCallback
|
||||
* when reference count becomes one.
|
||||
* One reference count is always added by TextureChild.
|
||||
*/
|
||||
void CompositorRecycle();
|
||||
|
||||
/**
|
||||
* Lock the texture host for compositing.
|
||||
*/
|
||||
@ -511,7 +502,8 @@ public:
|
||||
static PTextureParent* CreateIPDLActor(HostIPCAllocator* aAllocator,
|
||||
const SurfaceDescriptor& aSharedData,
|
||||
LayersBackend aLayersBackend,
|
||||
TextureFlags aFlags);
|
||||
TextureFlags aFlags,
|
||||
uint64_t aSerial);
|
||||
static bool DestroyIPDLActor(PTextureParent* actor);
|
||||
|
||||
/**
|
||||
@ -526,6 +518,8 @@ public:
|
||||
*/
|
||||
static TextureHost* AsTextureHost(PTextureParent* actor);
|
||||
|
||||
static uint64_t GetTextureSerial(PTextureParent* actor);
|
||||
|
||||
/**
|
||||
* Return a pointer to the IPDLActor.
|
||||
*
|
||||
@ -570,6 +564,8 @@ public:
|
||||
MOZ_ASSERT(mCompositableCount >= 0);
|
||||
if (mCompositableCount == 0) {
|
||||
UnbindTextureSource();
|
||||
// Send mFwdTransactionId to client side if necessary.
|
||||
NotifyNotUsed();
|
||||
}
|
||||
}
|
||||
|
||||
@ -595,6 +591,8 @@ public:
|
||||
|
||||
virtual void WaitAcquireFenceHandleSyncComplete() {};
|
||||
|
||||
void SetLastFwdTransactionId(uint64_t aTransactionId);
|
||||
|
||||
virtual bool NeedsFenceHandle() { return false; }
|
||||
|
||||
virtual FenceHandle GetCompositorReleaseFence() { return FenceHandle(); }
|
||||
@ -606,6 +604,10 @@ public:
|
||||
|
||||
virtual Compositor* GetCompositor() = 0;
|
||||
|
||||
virtual GrallocTextureHostOGL* AsGrallocTextureHostOGL() { return nullptr; }
|
||||
|
||||
void CallNotifyNotUsed();
|
||||
|
||||
protected:
|
||||
void ReadUnlock();
|
||||
|
||||
@ -617,12 +619,19 @@ protected:
|
||||
|
||||
virtual void UpdatedInternal(const nsIntRegion *Region) {}
|
||||
|
||||
/**
|
||||
* Called when mCompositableCount becomes 0.
|
||||
*/
|
||||
void NotifyNotUsed();
|
||||
|
||||
PTextureParent* mActor;
|
||||
RefPtr<TextureReadLock> mReadLock;
|
||||
TextureFlags mFlags;
|
||||
int mCompositableCount;
|
||||
uint64_t mFwdTransactionId;
|
||||
|
||||
friend class TextureParent;
|
||||
friend class TiledLayerBufferComposite;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -48,7 +48,6 @@ public:
|
||||
virtual CompositorD3D11* AsCompositorD3D11() override { return this; }
|
||||
|
||||
virtual bool Initialize() override;
|
||||
virtual void Destroy() override {}
|
||||
|
||||
virtual TextureFactoryIdentifier
|
||||
GetTextureFactoryIdentifier() override;
|
||||
|
@ -27,7 +27,6 @@ public:
|
||||
virtual CompositorD3D9* AsCompositorD3D9() override { return this; }
|
||||
|
||||
virtual bool Initialize() override;
|
||||
virtual void Destroy() override {}
|
||||
|
||||
virtual TextureFactoryIdentifier
|
||||
GetTextureFactoryIdentifier() override;
|
||||
|
@ -85,20 +85,12 @@ AsyncTransactionTracker::NotifyCancel()
|
||||
}
|
||||
|
||||
Atomic<uint64_t> AsyncTransactionTrackersHolder::sSerialCounter(0);
|
||||
Mutex* AsyncTransactionTrackersHolder::sHolderLock = nullptr;
|
||||
|
||||
std::map<uint64_t, AsyncTransactionTrackersHolder*> AsyncTransactionTrackersHolder::sTrackersHolders;
|
||||
|
||||
AsyncTransactionTrackersHolder::AsyncTransactionTrackersHolder()
|
||||
: mSerial(GetNextSerial())
|
||||
, mIsTrackersHolderDestroyed(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(AsyncTransactionTrackersHolder);
|
||||
{
|
||||
MOZ_ASSERT(sHolderLock);
|
||||
MutexAutoLock lock(*sHolderLock);
|
||||
sTrackersHolders[mSerial] = this;
|
||||
}
|
||||
}
|
||||
|
||||
AsyncTransactionTrackersHolder::~AsyncTransactionTrackersHolder()
|
||||
@ -106,16 +98,6 @@ AsyncTransactionTrackersHolder::~AsyncTransactionTrackersHolder()
|
||||
if (!mIsTrackersHolderDestroyed) {
|
||||
DestroyAsyncTransactionTrackersHolder();
|
||||
}
|
||||
|
||||
{
|
||||
if (sHolderLock) {
|
||||
sHolderLock->Lock();
|
||||
}
|
||||
sTrackersHolders.erase(mSerial);
|
||||
if (sHolderLock) {
|
||||
sHolderLock->Unlock();
|
||||
}
|
||||
}
|
||||
MOZ_COUNT_DTOR(AsyncTransactionTrackersHolder);
|
||||
}
|
||||
|
||||
@ -132,7 +114,6 @@ AsyncTransactionTrackersHolder::HoldUntilComplete(AsyncTransactionTracker* aTran
|
||||
}
|
||||
|
||||
if (aTransactionTracker) {
|
||||
MutexAutoLock lock(*sHolderLock);
|
||||
mAsyncTransactionTrackers[aTransactionTracker->GetId()] = aTransactionTracker;
|
||||
}
|
||||
}
|
||||
@ -140,7 +121,6 @@ AsyncTransactionTrackersHolder::HoldUntilComplete(AsyncTransactionTracker* aTran
|
||||
void
|
||||
AsyncTransactionTrackersHolder::TransactionCompleteted(uint64_t aTransactionId)
|
||||
{
|
||||
MutexAutoLock lock(*sHolderLock);
|
||||
TransactionCompletetedInternal(aTransactionId);
|
||||
}
|
||||
|
||||
@ -166,45 +146,15 @@ AsyncTransactionTrackersHolder::SetReleaseFenceHandle(FenceHandle& aReleaseFence
|
||||
}
|
||||
}
|
||||
|
||||
/*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()
|
||||
{
|
||||
if (sHolderLock) {
|
||||
sHolderLock->Lock();
|
||||
}
|
||||
std::map<uint64_t, RefPtr<AsyncTransactionTracker> >::iterator it;
|
||||
for (it = mAsyncTransactionTrackers.begin();
|
||||
it != mAsyncTransactionTrackers.end(); it++) {
|
||||
it->second->NotifyCancel();
|
||||
}
|
||||
mAsyncTransactionTrackers.clear();
|
||||
if (sHolderLock) {
|
||||
sHolderLock->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -54,6 +54,8 @@ public:
|
||||
*/
|
||||
void WaitComplete();
|
||||
|
||||
uint32_t GetWaitCount() { return mWaitCount; }
|
||||
|
||||
private:
|
||||
~AsyncTransactionWaiter() {}
|
||||
|
||||
@ -106,14 +108,6 @@ public:
|
||||
protected:
|
||||
virtual ~AsyncTransactionTracker();
|
||||
|
||||
static void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
static void Finalize()
|
||||
{
|
||||
}
|
||||
|
||||
static uint64_t GetNextSerial()
|
||||
{
|
||||
return ++sSerialCounter;
|
||||
@ -125,10 +119,6 @@ protected:
|
||||
bool mCompleted;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* gecko does not provide atomic operation for uint64_t.
|
||||
* Ensure atomicity by using Mutex.
|
||||
*/
|
||||
static Atomic<uint64_t> sSerialCounter;
|
||||
};
|
||||
|
||||
@ -138,23 +128,6 @@ 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);
|
||||
@ -170,6 +143,8 @@ public:
|
||||
return mSerial;
|
||||
}
|
||||
|
||||
void DestroyAsyncTransactionTrackersHolder();
|
||||
|
||||
protected:
|
||||
|
||||
static uint64_t GetNextSerial()
|
||||
@ -183,24 +158,12 @@ protected:
|
||||
|
||||
void ClearAllAsyncTransactionTrackers();
|
||||
|
||||
void DestroyAsyncTransactionTrackersHolder();
|
||||
|
||||
uint64_t mSerial;
|
||||
const uint64_t mSerial;
|
||||
|
||||
bool mIsTrackersHolderDestroyed;
|
||||
std::map<uint64_t, RefPtr<AsyncTransactionTracker> > mAsyncTransactionTrackers;
|
||||
|
||||
/**
|
||||
* gecko does not provide atomic operation for uint64_t.
|
||||
* Ensure atomicity by using Mutex.
|
||||
*/
|
||||
static Atomic<uint64_t> sSerialCounter;
|
||||
static Mutex* sHolderLock;
|
||||
|
||||
/**
|
||||
* Map of all living AsyncTransactionTrackersHolder instances
|
||||
*/
|
||||
static std::map<uint64_t, AsyncTransactionTrackersHolder*> sTrackersHolders;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include "mozilla/layers/TextureClient.h" // for TextureClient
|
||||
#include "nsRegion.h" // for nsIntRegion
|
||||
#include "mozilla/gfx/Rect.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsTHashtable.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
@ -68,7 +70,8 @@ public:
|
||||
virtual PTextureChild* CreateTexture(
|
||||
const SurfaceDescriptor& aSharedData,
|
||||
LayersBackend aLayersBackend,
|
||||
TextureFlags aFlags) = 0;
|
||||
TextureFlags aFlags,
|
||||
uint64_t aSerial) = 0;
|
||||
|
||||
/**
|
||||
* Communicate to the compositor that aRegion in the texture identified by
|
||||
@ -132,8 +135,6 @@ public:
|
||||
TextureClient* aClientOnBlack,
|
||||
TextureClient* aClientOnWhite) = 0;
|
||||
|
||||
virtual void SendPendingAsyncMessges() = 0;
|
||||
|
||||
void IdentifyTextureHost(const TextureFactoryIdentifier& aIdentifier);
|
||||
|
||||
virtual int32_t GetMaxTextureSize() const override
|
||||
@ -166,6 +167,9 @@ public:
|
||||
return mTextureFactoryIdentifier;
|
||||
}
|
||||
|
||||
virtual void UpdateFwdTransactionId() = 0;
|
||||
virtual uint64_t GetFwdTransactionId() = 0;
|
||||
|
||||
int32_t GetSerial() { return mSerial; }
|
||||
|
||||
SyncObject* GetSyncObject() { return mSyncObject; }
|
||||
@ -177,6 +181,7 @@ protected:
|
||||
nsTArray<RefPtr<TextureClient> > mTexturesToRemove;
|
||||
nsTArray<RefPtr<CompositableClient>> mCompositableClientsToRemove;
|
||||
RefPtr<SyncObject> mSyncObject;
|
||||
|
||||
const int32_t mSerial;
|
||||
static mozilla::Atomic<int32_t> sSerialCounter;
|
||||
};
|
||||
|
@ -118,7 +118,33 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
|
||||
NS_ASSERTION(tiledHost, "The compositable is not tiled");
|
||||
|
||||
const SurfaceDescriptorTiles& tileDesc = op.tileLayerDescriptor();
|
||||
|
||||
bool success = tiledHost->UseTiledLayerBuffer(this, tileDesc);
|
||||
|
||||
const InfallibleTArray<TileDescriptor>& tileDescriptors = tileDesc.tiles();
|
||||
for (size_t i = 0; i < tileDescriptors.Length(); i++) {
|
||||
const TileDescriptor& tileDesc = tileDescriptors[i];
|
||||
if (tileDesc.type() != TileDescriptor::TTexturedTileDescriptor) {
|
||||
continue;
|
||||
}
|
||||
const TexturedTileDescriptor& texturedDesc = tileDesc.get_TexturedTileDescriptor();
|
||||
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(texturedDesc.textureParent());
|
||||
if (texture) {
|
||||
texture->SetLastFwdTransactionId(mFwdTransactionId);
|
||||
// Make sure that each texture was handled by the compositable
|
||||
// because the recycling logic depends on it.
|
||||
MOZ_ASSERT(texture->NumCompositableRefs() > 0);
|
||||
}
|
||||
if (texturedDesc.textureOnWhite().type() == MaybeTexture::TPTextureParent) {
|
||||
texture = TextureHost::AsTextureHost(texturedDesc.textureOnWhite().get_PTextureParent());
|
||||
if (texture) {
|
||||
texture->SetLastFwdTransactionId(mFwdTransactionId);
|
||||
// Make sure that each texture was handled by the compositable
|
||||
// because the recycling logic depends on it.
|
||||
MOZ_ASSERT(texture->NumCompositableRefs() > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
@ -131,8 +157,6 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
|
||||
|
||||
MOZ_ASSERT(tex.get());
|
||||
compositable->RemoveTextureHost(tex);
|
||||
// send FenceHandle if present.
|
||||
SendFenceHandleIfPresent(op.textureParent());
|
||||
break;
|
||||
}
|
||||
case CompositableOperationDetail::TOpRemoveTextureAsync: {
|
||||
@ -142,24 +166,9 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
|
||||
MOZ_ASSERT(tex.get());
|
||||
compositable->RemoveTextureHost(tex);
|
||||
|
||||
if (!UsesImageBridge() && ImageBridgeParent::GetInstance(GetChildProcessId())) {
|
||||
// send FenceHandle if present via ImageBridge.
|
||||
ImageBridgeParent::AppendDeliverFenceMessage(
|
||||
GetChildProcessId(),
|
||||
op.holderId(),
|
||||
op.transactionId(),
|
||||
op.textureParent());
|
||||
|
||||
// If the message is recievied via PLayerTransaction,
|
||||
// Send message back via PImageBridge.
|
||||
ImageBridgeParent::ReplyRemoveTexture(
|
||||
GetChildProcessId(),
|
||||
OpReplyRemoveTexture(op.holderId(),
|
||||
op.transactionId()));
|
||||
} else {
|
||||
// send FenceHandle if present.
|
||||
SendFenceHandleIfPresent(op.textureParent());
|
||||
|
||||
// Only ImageBridge child sends it.
|
||||
MOZ_ASSERT(UsesImageBridge());
|
||||
if (UsesImageBridge()) {
|
||||
ReplyRemoveTexture(OpReplyRemoveTexture(op.holderId(),
|
||||
op.transactionId()));
|
||||
}
|
||||
@ -192,6 +201,16 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
|
||||
}
|
||||
if (textures.Length() > 0) {
|
||||
compositable->UseTextureHost(textures);
|
||||
|
||||
for (auto& timedTexture : op.textures()) {
|
||||
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(timedTexture.textureParent());
|
||||
if (texture) {
|
||||
texture->SetLastFwdTransactionId(mFwdTransactionId);
|
||||
// Make sure that each texture was handled by the compositable
|
||||
// because the recycling logic depends on it.
|
||||
MOZ_ASSERT(texture->NumCompositableRefs() > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (UsesImageBridge() && compositable->GetLayer()) {
|
||||
@ -205,9 +224,24 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
|
||||
RefPtr<TextureHost> texOnWhite = TextureHost::AsTextureHost(op.textureOnWhiteParent());
|
||||
texOnBlack->DeserializeReadLock(op.sharedLockBlack(), this);
|
||||
texOnWhite->DeserializeReadLock(op.sharedLockWhite(), this);
|
||||
|
||||
MOZ_ASSERT(texOnBlack && texOnWhite);
|
||||
compositable->UseComponentAlphaTextures(texOnBlack, texOnWhite);
|
||||
|
||||
if (texOnBlack) {
|
||||
texOnBlack->SetLastFwdTransactionId(mFwdTransactionId);
|
||||
// Make sure that each texture was handled by the compositable
|
||||
// because the recycling logic depends on it.
|
||||
MOZ_ASSERT(texOnBlack->NumCompositableRefs() > 0);
|
||||
}
|
||||
|
||||
if (texOnWhite) {
|
||||
texOnWhite->SetLastFwdTransactionId(mFwdTransactionId);
|
||||
// Make sure that each texture was handled by the compositable
|
||||
// because the recycling logic depends on it.
|
||||
MOZ_ASSERT(texOnWhite->NumCompositableRefs() > 0);
|
||||
}
|
||||
|
||||
if (UsesImageBridge()) {
|
||||
ScheduleComposition(compositable);
|
||||
}
|
||||
@ -251,42 +285,6 @@ CompositableParentManager::DestroyActor(const OpDestroy& aOp)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CompositableParentManager::SendPendingAsyncMessages()
|
||||
{
|
||||
if (mPendingAsyncMessage.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Some type of AsyncParentMessageData message could have
|
||||
// one file descriptor (e.g. OpDeliverFence).
|
||||
// A number of file descriptors per gecko ipc message have a limitation
|
||||
// on OS_POSIX (MACOSX or LINUX).
|
||||
#if defined(OS_POSIX)
|
||||
static const uint32_t kMaxMessageNumber = FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE;
|
||||
#else
|
||||
// default number that works everywhere else
|
||||
static const uint32_t kMaxMessageNumber = 250;
|
||||
#endif
|
||||
|
||||
InfallibleTArray<AsyncParentMessageData> messages;
|
||||
messages.SetCapacity(mPendingAsyncMessage.size());
|
||||
for (size_t i = 0; i < mPendingAsyncMessage.size(); i++) {
|
||||
messages.AppendElement(mPendingAsyncMessage[i]);
|
||||
// Limit maximum number of messages.
|
||||
if (messages.Length() >= kMaxMessageNumber) {
|
||||
SendAsyncMessage(messages);
|
||||
// Initialize Messages.
|
||||
messages.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (messages.Length() > 0) {
|
||||
SendAsyncMessage(messages);
|
||||
}
|
||||
mPendingAsyncMessage.clear();
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -28,14 +28,16 @@ typedef std::vector<mozilla::layers::EditReply> EditReplyVector;
|
||||
class CompositableParentManager : public HostIPCAllocator
|
||||
{
|
||||
public:
|
||||
virtual void SendFenceHandleIfPresent(PTextureParent* aTexture) = 0;
|
||||
|
||||
virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) = 0;
|
||||
|
||||
void SendPendingAsyncMessages();
|
||||
|
||||
void DestroyActor(const OpDestroy& aOp);
|
||||
|
||||
void UpdateFwdTransactionId(uint64_t aTransactionId)
|
||||
{
|
||||
MOZ_ASSERT(mFwdTransactionId < aTransactionId);
|
||||
mFwdTransactionId = aTransactionId;
|
||||
}
|
||||
|
||||
uint64_t GetFwdTransactionId() { return mFwdTransactionId; }
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Handle the IPDL messages that affect PCompositable actors.
|
||||
@ -43,9 +45,9 @@ protected:
|
||||
bool ReceiveCompositableUpdate(const CompositableOperation& aEdit,
|
||||
EditReplyVector& replyv);
|
||||
|
||||
virtual void ReplyRemoveTexture(const OpReplyRemoveTexture& aReply) {}
|
||||
virtual void ReplyRemoveTexture(const OpReplyRemoveTexture& aReply) {};
|
||||
|
||||
std::vector<AsyncParentMessageData> mPendingAsyncMessage;
|
||||
uint64_t mFwdTransactionId = 0;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "base/task.h" // for NewRunnableMethod, etc
|
||||
#include "mozilla/layers/LayerTransactionChild.h"
|
||||
#include "mozilla/layers/PLayerTransactionChild.h"
|
||||
#include "mozilla/layers/TextureClient.h"// for TextureClient
|
||||
#include "mozilla/mozalloc.h" // for operator new, etc
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsDebug.h" // for NS_RUNTIMEABORT
|
||||
@ -42,6 +43,7 @@ Atomic<int32_t> CompositableForwarder::sSerialCounter(0);
|
||||
CompositorBridgeChild::CompositorBridgeChild(ClientLayerManager *aLayerManager)
|
||||
: mLayerManager(aLayerManager)
|
||||
, mCanSend(false)
|
||||
, mFwdTransactionId(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -76,6 +78,7 @@ CompositorBridgeChild::Destroy()
|
||||
{
|
||||
// This must not be called from the destructor!
|
||||
MOZ_ASSERT(mRefCnt != 0);
|
||||
mTexturesWaitingRecycled.Clear();
|
||||
|
||||
if (!mCanSend) {
|
||||
return;
|
||||
@ -766,7 +769,8 @@ PTextureChild*
|
||||
CompositorBridgeChild::AllocPTextureChild(const SurfaceDescriptor&,
|
||||
const LayersBackend&,
|
||||
const TextureFlags&,
|
||||
const uint64_t&)
|
||||
const uint64_t&,
|
||||
const uint64_t& aSerial)
|
||||
{
|
||||
return TextureClient::CreateIPDLActor();
|
||||
}
|
||||
@ -777,6 +781,90 @@ CompositorBridgeChild::DeallocPTextureChild(PTextureChild* actor)
|
||||
return TextureClient::DestroyIPDLActor(actor);
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorBridgeChild::RecvParentAsyncMessages(InfallibleTArray<AsyncParentMessageData>&& aMessages)
|
||||
{
|
||||
for (AsyncParentMessageArray::index_type i = 0; i < aMessages.Length(); ++i) {
|
||||
const AsyncParentMessageData& message = aMessages[i];
|
||||
|
||||
switch (message.type()) {
|
||||
case AsyncParentMessageData::TOpDeliverFence: {
|
||||
const OpDeliverFence& op = message.get_OpDeliverFence();
|
||||
FenceHandle fence = op.fence();
|
||||
DeliverFence(op.TextureId(), fence);
|
||||
break;
|
||||
}
|
||||
case AsyncParentMessageData::TOpNotifyNotUsed: {
|
||||
const OpNotifyNotUsed& op = message.get_OpNotifyNotUsed();
|
||||
NotifyNotUsed(op.TextureId(), op.fwdTransactionId());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NS_ERROR("unknown AsyncParentMessageData type");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeChild::HoldUntilCompositableRefReleasedIfNecessary(TextureClient* aClient)
|
||||
{
|
||||
if (!aClient) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(aClient->GetFlags() & TextureFlags::RECYCLE) &&
|
||||
!aClient->NeedsFenceHandle()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aClient->GetFlags() & TextureFlags::RECYCLE) {
|
||||
aClient->SetLastFwdTransactionId(GetFwdTransactionId());
|
||||
mTexturesWaitingRecycled.Put(aClient->GetSerial(), aClient);
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(!(aClient->GetFlags() & TextureFlags::RECYCLE));
|
||||
MOZ_ASSERT(aClient->NeedsFenceHandle());
|
||||
// Handle a case of fence delivery via ImageBridge.
|
||||
// GrallocTextureData alwasys requests fence delivery if ANDROID_VERSION >= 17.
|
||||
ImageBridgeChild::GetSingleton()->HoldUntilFenceHandleDelivery(aClient, GetFwdTransactionId());
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeChild::NotifyNotUsed(uint64_t aTextureId, uint64_t aFwdTransactionId)
|
||||
{
|
||||
RefPtr<TextureClient> client = mTexturesWaitingRecycled.Get(aTextureId);
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
if (aFwdTransactionId < client->GetLastFwdTransactionId()) {
|
||||
// Released on host side, but client already requested newer use texture.
|
||||
return;
|
||||
}
|
||||
mTexturesWaitingRecycled.Remove(aTextureId);
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeChild::DeliverFence(uint64_t aTextureId, FenceHandle& aReleaseFenceHandle)
|
||||
{
|
||||
RefPtr<TextureClient> client = mTexturesWaitingRecycled.Get(aTextureId);
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
client->SetReleaseFenceHandle(aReleaseFenceHandle);
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeChild::CancelWaitForRecycle(uint64_t aTextureId)
|
||||
{
|
||||
RefPtr<TextureClient> client = mTexturesWaitingRecycled.Get(aTextureId);
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
mTexturesWaitingRecycled.Remove(aTextureId);
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -31,10 +31,13 @@ using mozilla::dom::TabChild;
|
||||
|
||||
class ClientLayerManager;
|
||||
class CompositorBridgeParent;
|
||||
class TextureClient;
|
||||
struct FrameMetrics;
|
||||
|
||||
class CompositorBridgeChild final : public PCompositorBridgeChild
|
||||
{
|
||||
typedef InfallibleTArray<AsyncParentMessageData> AsyncParentMessageArray;
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorBridgeChild)
|
||||
|
||||
public:
|
||||
@ -98,10 +101,14 @@ public:
|
||||
virtual PTextureChild* AllocPTextureChild(const SurfaceDescriptor& aSharedData,
|
||||
const LayersBackend& aLayersBackend,
|
||||
const TextureFlags& aFlags,
|
||||
const uint64_t& aId) override;
|
||||
const uint64_t& aId,
|
||||
const uint64_t& aSerial) override;
|
||||
|
||||
virtual bool DeallocPTextureChild(PTextureChild* actor) override;
|
||||
|
||||
virtual bool
|
||||
RecvParentAsyncMessages(InfallibleTArray<AsyncParentMessageData>&& aMessages) override;
|
||||
|
||||
/**
|
||||
* Request that the parent tell us when graphics are ready on GPU.
|
||||
* When we get that message, we bounce it to the TabParent via
|
||||
@ -140,6 +147,25 @@ public:
|
||||
|
||||
static void ShutDown();
|
||||
|
||||
void UpdateFwdTransactionId() { ++mFwdTransactionId; }
|
||||
uint64_t GetFwdTransactionId() { return mFwdTransactionId; }
|
||||
|
||||
/**
|
||||
* Hold TextureClient ref until end of usage on host side if TextureFlags::RECYCLE is set.
|
||||
* Host side's usage is checked via CompositableRef.
|
||||
*/
|
||||
void HoldUntilCompositableRefReleasedIfNecessary(TextureClient* aClient);
|
||||
|
||||
/**
|
||||
* Notify id of Texture When host side end its use. Transaction id is used to
|
||||
* make sure if there is no newer usage.
|
||||
*/
|
||||
void NotifyNotUsed(uint64_t aTextureId, uint64_t aFwdTransactionId);
|
||||
|
||||
void DeliverFence(uint64_t aTextureId, FenceHandle& aReleaseFenceHandle);
|
||||
|
||||
void CancelWaitForRecycle(uint64_t aTextureId);
|
||||
|
||||
private:
|
||||
// Private destructor, to discourage deletion outside of Release():
|
||||
virtual ~CompositorBridgeChild();
|
||||
@ -211,6 +237,18 @@ private:
|
||||
|
||||
// True until the beginning of the two-step shutdown sequence of this actor.
|
||||
bool mCanSend;
|
||||
|
||||
/**
|
||||
* Transaction id of ShadowLayerForwarder.
|
||||
* It is incrementaed by UpdateFwdTransactionId() in each BeginTransaction() call.
|
||||
*/
|
||||
uint64_t mFwdTransactionId;
|
||||
|
||||
/**
|
||||
* Hold TextureClients refs until end of their usages on host side.
|
||||
* It defer calling of TextureClient recycle callback.
|
||||
*/
|
||||
nsDataHashtable<nsUint64HashKey, RefPtr<TextureClient> > mTexturesWaitingRecycled;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
@ -1815,7 +1815,7 @@ CompositorBridgeParent::RequestNotifyLayerTreeCleared(uint64_t aLayersId, Compos
|
||||
*/
|
||||
class CrossProcessCompositorBridgeParent final : public PCompositorBridgeParent,
|
||||
public ShadowLayersManager,
|
||||
public HostIPCAllocator,
|
||||
public CompositorBridgeParentIPCAllocator,
|
||||
public ShmemAllocator
|
||||
{
|
||||
friend class CompositorBridgeParent;
|
||||
@ -1956,7 +1956,8 @@ public:
|
||||
virtual PTextureParent* AllocPTextureParent(const SurfaceDescriptor& aSharedData,
|
||||
const LayersBackend& aLayersBackend,
|
||||
const TextureFlags& aFlags,
|
||||
const uint64_t& aId) override;
|
||||
const uint64_t& aId,
|
||||
const uint64_t& aSerial) override;
|
||||
|
||||
virtual bool DeallocPTextureParent(PTextureParent* actor) override;
|
||||
|
||||
@ -1979,6 +1980,13 @@ public:
|
||||
return OtherPid();
|
||||
}
|
||||
|
||||
virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) override
|
||||
{
|
||||
Unused << SendParentAsyncMessages(aMessage);
|
||||
}
|
||||
|
||||
virtual CompositorBridgeParentIPCAllocator* AsCompositorBridgeParentIPCAllocator() override { return this; }
|
||||
|
||||
protected:
|
||||
void OnChannelConnected(int32_t pid) override {
|
||||
mCompositorThreadHolder = CompositorThreadHolder::GetSingleton();
|
||||
@ -2198,9 +2206,10 @@ PTextureParent*
|
||||
CompositorBridgeParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
|
||||
const LayersBackend& aLayersBackend,
|
||||
const TextureFlags& aFlags,
|
||||
const uint64_t& aId)
|
||||
const uint64_t& aId,
|
||||
const uint64_t& aSerial)
|
||||
{
|
||||
return TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags);
|
||||
return TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags, aSerial);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2231,6 +2240,12 @@ CompositorBridgeParent::DeallocShmem(ipc::Shmem& aShmem)
|
||||
PCompositorBridgeParent::DeallocShmem(aShmem);
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeParent::SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage)
|
||||
{
|
||||
Unused << SendParentAsyncMessages(aMessage);
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorBridgeParent::IsSameProcess() const
|
||||
{
|
||||
@ -2763,7 +2778,8 @@ PTextureParent*
|
||||
CrossProcessCompositorBridgeParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
|
||||
const LayersBackend& aLayersBackend,
|
||||
const TextureFlags& aFlags,
|
||||
const uint64_t& aId)
|
||||
const uint64_t& aId,
|
||||
const uint64_t& aSerial)
|
||||
{
|
||||
CompositorBridgeParent::LayerTreeState* state = nullptr;
|
||||
|
||||
@ -2786,7 +2802,7 @@ CrossProcessCompositorBridgeParent::AllocPTextureParent(const SurfaceDescriptor&
|
||||
gfxDevCrash(gfx::LogReason::PAllocTextureBackendMismatch) << "Texture backend is wrong";
|
||||
}
|
||||
|
||||
return TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags);
|
||||
return TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags, aSerial);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -204,7 +204,7 @@ protected:
|
||||
|
||||
class CompositorBridgeParent final : public PCompositorBridgeParent,
|
||||
public ShadowLayersManager,
|
||||
public HostIPCAllocator,
|
||||
public CompositorBridgeParentIPCAllocator,
|
||||
public ShmemAllocator
|
||||
{
|
||||
friend class CompositorVsyncScheduler;
|
||||
@ -288,7 +288,8 @@ public:
|
||||
virtual PTextureParent* AllocPTextureParent(const SurfaceDescriptor& aSharedData,
|
||||
const LayersBackend& aLayersBackend,
|
||||
const TextureFlags& aFlags,
|
||||
const uint64_t& aId) override;
|
||||
const uint64_t& aId,
|
||||
const uint64_t& aSerial) override;
|
||||
virtual bool DeallocPTextureParent(PTextureParent* actor) override;
|
||||
|
||||
virtual bool IsSameProcess() const override;
|
||||
@ -309,6 +310,11 @@ public:
|
||||
{
|
||||
return OtherPid();
|
||||
}
|
||||
|
||||
virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) override;
|
||||
|
||||
virtual CompositorBridgeParentIPCAllocator* AsCompositorBridgeParentIPCAllocator() override { return this; }
|
||||
|
||||
/**
|
||||
* Request that the compositor be recreated due to a shared device reset.
|
||||
* This must be called on the main thread, and blocks until a task posted
|
||||
|
@ -7,6 +7,9 @@
|
||||
|
||||
#include "ISurfaceAllocator.h"
|
||||
|
||||
#include "mozilla/layers/ImageBridgeParent.h" // for ImageBridgeParent
|
||||
#include "mozilla/layers/TextureHost.h" // for TextureHost
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
@ -19,5 +22,111 @@ mozilla::ipc::SharedMemory::SharedMemoryType OptimalShmemType()
|
||||
return ipc::SharedMemory::SharedMemoryType::TYPE_BASIC;
|
||||
}
|
||||
|
||||
void
|
||||
HostIPCAllocator::SendFenceHandleIfPresent(PTextureParent* aTexture)
|
||||
{
|
||||
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
|
||||
if (!texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(texture->GetFlags() & TextureFlags::RECYCLE) &&
|
||||
!texture->NeedsFenceHandle()) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t textureId = TextureHost::GetTextureSerial(aTexture);
|
||||
|
||||
// Send a ReleaseFence of CompositorOGL.
|
||||
FenceHandle fence = texture->GetCompositorReleaseFence();
|
||||
if (fence.IsValid()) {
|
||||
mPendingAsyncMessage.push_back(OpDeliverFence(textureId, fence));
|
||||
}
|
||||
|
||||
// Send a ReleaseFence that is set to TextureHost by HwcComposer2D.
|
||||
fence = texture->GetAndResetReleaseFenceHandle();
|
||||
if (fence.IsValid()) {
|
||||
mPendingAsyncMessage.push_back(OpDeliverFence(textureId, fence));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HostIPCAllocator::SendPendingAsyncMessages()
|
||||
{
|
||||
if (mPendingAsyncMessage.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Some type of AsyncParentMessageData message could have
|
||||
// one file descriptor (e.g. OpDeliverFence).
|
||||
// A number of file descriptors per gecko ipc message have a limitation
|
||||
// on OS_POSIX (MACOSX or LINUX).
|
||||
#if defined(OS_POSIX)
|
||||
static const uint32_t kMaxMessageNumber = FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE;
|
||||
#else
|
||||
// default number that works everywhere else
|
||||
static const uint32_t kMaxMessageNumber = 250;
|
||||
#endif
|
||||
|
||||
InfallibleTArray<AsyncParentMessageData> messages;
|
||||
messages.SetCapacity(mPendingAsyncMessage.size());
|
||||
for (size_t i = 0; i < mPendingAsyncMessage.size(); i++) {
|
||||
messages.AppendElement(mPendingAsyncMessage[i]);
|
||||
// Limit maximum number of messages.
|
||||
if (messages.Length() >= kMaxMessageNumber) {
|
||||
SendAsyncMessage(messages);
|
||||
// Initialize Messages.
|
||||
messages.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (messages.Length() > 0) {
|
||||
SendAsyncMessage(messages);
|
||||
}
|
||||
mPendingAsyncMessage.clear();
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeParentIPCAllocator::NotifyNotUsed(PTextureParent* aTexture, uint64_t aTransactionId)
|
||||
{
|
||||
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
|
||||
if (!texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(texture->GetFlags() & TextureFlags::RECYCLE) &&
|
||||
!texture->NeedsFenceHandle()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (texture->GetFlags() & TextureFlags::RECYCLE) {
|
||||
SendFenceHandleIfPresent(aTexture);
|
||||
uint64_t textureId = TextureHost::GetTextureSerial(aTexture);
|
||||
mPendingAsyncMessage.push_back(
|
||||
OpNotifyNotUsed(textureId, aTransactionId));
|
||||
return;
|
||||
}
|
||||
|
||||
// Gralloc requests to deliver fence to client side.
|
||||
// If client side does not use TextureFlags::RECYCLE flag,
|
||||
// The fence can not be delivered via LayerTransactionParent.
|
||||
// TextureClient might wait the fence delivery on main thread.
|
||||
|
||||
MOZ_ASSERT(ImageBridgeParent::GetInstance(GetChildProcessId()));
|
||||
if (ImageBridgeParent::GetInstance(GetChildProcessId())) {
|
||||
// Send message back via PImageBridge.
|
||||
ImageBridgeParent::NotifyNotUsedToNonRecycle(
|
||||
GetChildProcessId(),
|
||||
aTexture,
|
||||
aTransactionId);
|
||||
} else {
|
||||
NS_ERROR("ImageBridgeParent should exist");
|
||||
}
|
||||
|
||||
if (!IsAboutToSendAsyncMessages()) {
|
||||
SendPendingAsyncMessages();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
@ -123,6 +123,8 @@ public:
|
||||
virtual MessageLoop * GetMessageLoop() const = 0;
|
||||
|
||||
virtual int32_t GetMaxTextureSize() const { return gfxPrefs::MaxTextureSize(); }
|
||||
|
||||
virtual void CancelWaitForRecycle(uint64_t aTextureId) = 0;
|
||||
};
|
||||
|
||||
/// Methods that are specific to the host/parent side.
|
||||
@ -135,8 +137,36 @@ public:
|
||||
* Get child side's process Id.
|
||||
*/
|
||||
virtual base::ProcessId GetChildProcessId() = 0;
|
||||
|
||||
virtual void NotifyNotUsed(PTextureParent* aTexture, uint64_t aTransactionId) = 0;
|
||||
|
||||
virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) = 0;
|
||||
|
||||
void SendFenceHandleIfPresent(PTextureParent* aTexture);
|
||||
|
||||
virtual void SendPendingAsyncMessages();
|
||||
|
||||
virtual void SetAboutToSendAsyncMessages()
|
||||
{
|
||||
mAboutToSendAsyncMessages = true;
|
||||
}
|
||||
|
||||
bool IsAboutToSendAsyncMessages()
|
||||
{
|
||||
return mAboutToSendAsyncMessages;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::vector<AsyncParentMessageData> mPendingAsyncMessage;
|
||||
bool mAboutToSendAsyncMessages = false;
|
||||
};
|
||||
|
||||
/// Specific to the CompositorBridgeParent/CrossProcessCompositorBridgeParent.
|
||||
class CompositorBridgeParentIPCAllocator : public HostIPCAllocator
|
||||
{
|
||||
public:
|
||||
virtual void NotifyNotUsed(PTextureParent* aTexture, uint64_t aTransactionId) override;
|
||||
};
|
||||
|
||||
/// An allocator can provide shared memory.
|
||||
///
|
||||
|
@ -195,6 +195,9 @@ ImageBridgeChild::UseTextures(CompositableClient* aCompositable,
|
||||
fence.IsValid() ? MaybeFence(fence) : MaybeFence(null_t()),
|
||||
t.mTimeStamp, t.mPictureRect,
|
||||
t.mFrameID, t.mProducerID, t.mInputFrameID));
|
||||
|
||||
// Wait end of usage on host side if TextureFlags::RECYCLE is set or GrallocTextureData case
|
||||
HoldUntilCompositableRefReleasedIfNecessary(t.mTextureClient);
|
||||
}
|
||||
mTxn->AddNoSwapEdit(CompositableOperation(nullptr, aCompositable->GetIPDLActor(),
|
||||
OpUseTexture(textures)));
|
||||
@ -218,6 +221,9 @@ ImageBridgeChild::UseComponentAlphaTextures(CompositableClient* aCompositable,
|
||||
aTextureOnBlack->SerializeReadLock(readLockB);
|
||||
aTextureOnWhite->SerializeReadLock(readLockW);
|
||||
|
||||
HoldUntilCompositableRefReleasedIfNecessary(aTextureOnBlack);
|
||||
HoldUntilCompositableRefReleasedIfNecessary(aTextureOnWhite);
|
||||
|
||||
mTxn->AddNoSwapEdit(
|
||||
CompositableOperation(
|
||||
nullptr,
|
||||
@ -249,6 +255,127 @@ ImageBridgeChild::UseOverlaySource(CompositableClient* aCompositable,
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
ImageBridgeChild::HoldUntilCompositableRefReleasedIfNecessary(TextureClient* aClient)
|
||||
{
|
||||
// Wait ReleaseCompositableRef only when TextureFlags::RECYCLE is set on ImageBridge.
|
||||
if (!aClient ||
|
||||
!(aClient->GetFlags() & TextureFlags::RECYCLE)) {
|
||||
return;
|
||||
}
|
||||
aClient->SetLastFwdTransactionId(GetFwdTransactionId());
|
||||
mTexturesWaitingRecycled.Put(aClient->GetSerial(), aClient);
|
||||
}
|
||||
|
||||
void
|
||||
ImageBridgeChild::NotifyNotUsed(uint64_t aTextureId, uint64_t aFwdTransactionId)
|
||||
{
|
||||
RefPtr<TextureClient> client = mTexturesWaitingRecycled.Get(aTextureId);
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
if (aFwdTransactionId < client->GetLastFwdTransactionId()) {
|
||||
// Released on host side, but client already requested newer use texture.
|
||||
return;
|
||||
}
|
||||
mTexturesWaitingRecycled.Remove(aTextureId);
|
||||
}
|
||||
|
||||
void
|
||||
ImageBridgeChild::DeliverFence(uint64_t aTextureId, FenceHandle& aReleaseFenceHandle)
|
||||
{
|
||||
RefPtr<TextureClient> client = mTexturesWaitingRecycled.Get(aTextureId);
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
client->SetReleaseFenceHandle(aReleaseFenceHandle);
|
||||
}
|
||||
|
||||
void
|
||||
ImageBridgeChild::HoldUntilFenceHandleDelivery(TextureClient* aClient, uint64_t aTransactionId)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
if (!aClient) {
|
||||
return;
|
||||
}
|
||||
MutexAutoLock lock(mWaitingFenceHandleMutex);
|
||||
aClient->SetLastFwdTransactionId(aTransactionId);
|
||||
aClient->WaitFenceHandleOnImageBridge(mWaitingFenceHandleMutex);
|
||||
mTexturesWaitingFenceHandle.Put(aClient->GetSerial(), aClient);
|
||||
#else
|
||||
NS_RUNTIMEABORT("not reached");
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
ImageBridgeChild::DeliverFenceToNonRecycle(uint64_t aTextureId, FenceHandle& aReleaseFenceHandle)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
MutexAutoLock lock(mWaitingFenceHandleMutex);
|
||||
TextureClient* client = mTexturesWaitingFenceHandle.Get(aTextureId).get();
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(aTextureId == client->GetSerial());
|
||||
client->SetReleaseFenceHandle(aReleaseFenceHandle);
|
||||
#else
|
||||
NS_RUNTIMEABORT("not reached");
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
ImageBridgeChild::NotifyNotUsedToNonRecycle(uint64_t aTextureId, uint64_t aTransactionId)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
MutexAutoLock lock(mWaitingFenceHandleMutex);
|
||||
|
||||
RefPtr<TextureClient> client = mTexturesWaitingFenceHandle.Get(aTextureId);
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
if (aTransactionId < client->GetLastFwdTransactionId()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aTextureId == client->GetSerial());
|
||||
client->ClearWaitFenceHandleOnImageBridge(mWaitingFenceHandleMutex);
|
||||
mTexturesWaitingFenceHandle.Remove(aTextureId);
|
||||
|
||||
// Release TextureClient on allocator's message loop.
|
||||
TextureClientReleaseTask* task = new TextureClientReleaseTask(client);
|
||||
RefPtr<ClientIPCAllocator> allocator = client->GetAllocator();
|
||||
client = nullptr;
|
||||
allocator->AsClientAllocator()->GetMessageLoop()->PostTask(FROM_HERE, task);
|
||||
#else
|
||||
NS_RUNTIMEABORT("not reached");
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
ImageBridgeChild::CancelWaitFenceHandle(TextureClient* aClient)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
MutexAutoLock lock(mWaitingFenceHandleMutex);
|
||||
aClient->ClearWaitFenceHandleOnImageBridge(mWaitingFenceHandleMutex);
|
||||
mTexturesWaitingFenceHandle.Remove(aClient->GetSerial());
|
||||
#else
|
||||
NS_RUNTIMEABORT("not reached");
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
ImageBridgeChild::CancelWaitForRecycle(uint64_t aTextureId)
|
||||
{
|
||||
MOZ_ASSERT(InImageBridgeChildThread());
|
||||
|
||||
RefPtr<TextureClient> client = mTexturesWaitingRecycled.Get(aTextureId);
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
mTexturesWaitingRecycled.Remove(aTextureId);
|
||||
}
|
||||
|
||||
// Singleton
|
||||
static StaticRefPtr<ImageBridgeChild> sImageBridgeChildSingleton;
|
||||
static StaticRefPtr<ImageBridgeParent> sImageBridgeParentSingleton;
|
||||
@ -355,6 +482,10 @@ static void ConnectImageBridge(ImageBridgeChild * child, ImageBridgeParent * par
|
||||
|
||||
ImageBridgeChild::ImageBridgeChild()
|
||||
: mShuttingDown(false)
|
||||
, mFwdTransactionId(0)
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
, mWaitingFenceHandleMutex("ImageBridgeChild::mWaitingFenceHandleMutex")
|
||||
#endif
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
@ -378,6 +509,9 @@ void
|
||||
ImageBridgeChild::MarkShutDown()
|
||||
{
|
||||
MOZ_ASSERT(!mShuttingDown);
|
||||
mTexturesWaitingRecycled.Clear();
|
||||
mTrackersHolder.DestroyAsyncTransactionTrackersHolder();
|
||||
|
||||
mShuttingDown = true;
|
||||
}
|
||||
|
||||
@ -720,6 +854,7 @@ ImageBridgeChild::BeginTransaction()
|
||||
{
|
||||
MOZ_ASSERT(!mShuttingDown);
|
||||
MOZ_ASSERT(mTxn->Finished(), "uncommitted txn?");
|
||||
UpdateFwdTransactionId();
|
||||
mTxn->Begin();
|
||||
}
|
||||
|
||||
@ -748,7 +883,7 @@ ImageBridgeChild::EndTransaction()
|
||||
AutoTArray<EditReply, 10> replies;
|
||||
|
||||
if (mTxn->mSwapRequired) {
|
||||
if (!SendUpdate(cset, mTxn->mDestroyedActors, &replies)) {
|
||||
if (!SendUpdate(cset, mTxn->mDestroyedActors, GetFwdTransactionId(), &replies)) {
|
||||
NS_WARNING("could not send async texture transaction");
|
||||
mTxn->FallbackDestroyActors();
|
||||
return;
|
||||
@ -756,7 +891,7 @@ ImageBridgeChild::EndTransaction()
|
||||
} else {
|
||||
// If we don't require a swap we can call SendUpdateNoSwap which
|
||||
// assumes that aReplies is empty (DEBUG assertion)
|
||||
if (!SendUpdateNoSwap(cset, mTxn->mDestroyedActors)) {
|
||||
if (!SendUpdateNoSwap(cset, mTxn->mDestroyedActors, GetFwdTransactionId())) {
|
||||
NS_WARNING("could not send async texture transaction (no swap)");
|
||||
mTxn->FallbackDestroyActors();
|
||||
return;
|
||||
@ -765,7 +900,6 @@ ImageBridgeChild::EndTransaction()
|
||||
for (nsTArray<EditReply>::size_type i = 0; i < replies.Length(); ++i) {
|
||||
NS_RUNTIMEABORT("not reached");
|
||||
}
|
||||
SendPendingAsyncMessges();
|
||||
}
|
||||
|
||||
void
|
||||
@ -1093,7 +1227,8 @@ ImageBridgeChild::DeallocShmem(ipc::Shmem& aShmem)
|
||||
PTextureChild*
|
||||
ImageBridgeChild::AllocPTextureChild(const SurfaceDescriptor&,
|
||||
const LayersBackend&,
|
||||
const TextureFlags&)
|
||||
const TextureFlags&,
|
||||
const uint64_t& aSerial)
|
||||
{
|
||||
MOZ_ASSERT(!mShuttingDown);
|
||||
return TextureClient::CreateIPDLActor();
|
||||
@ -1145,28 +1280,40 @@ ImageBridgeChild::RecvParentAsyncMessages(InfallibleTArray<AsyncParentMessageDat
|
||||
case AsyncParentMessageData::TOpDeliverFence: {
|
||||
const OpDeliverFence& op = message.get_OpDeliverFence();
|
||||
FenceHandle fence = op.fence();
|
||||
PTextureChild* child = op.textureChild();
|
||||
|
||||
RefPtr<TextureClient> texture = TextureClient::AsTextureClient(child);
|
||||
if (texture) {
|
||||
texture->SetReleaseFenceHandle(fence);
|
||||
}
|
||||
DeliverFence(op.TextureId(), fence);
|
||||
break;
|
||||
}
|
||||
case AsyncParentMessageData::TOpDeliverFenceToTracker: {
|
||||
const OpDeliverFenceToTracker& op = message.get_OpDeliverFenceToTracker();
|
||||
FenceHandle fence = op.fence();
|
||||
case AsyncParentMessageData::TOpDeliverFenceToNonRecycle: {
|
||||
// Notify ReleaseCompositableRef to a TextureClient that belongs to
|
||||
// LayerTransactionChild. It is used only on gonk to deliver fence to
|
||||
// a TextureClient that does not have TextureFlags::RECYCLE.
|
||||
// In this case, LayerTransactionChild's ipc could not be used to deliver fence.
|
||||
|
||||
AsyncTransactionTrackersHolder::SetReleaseFenceHandle(fence,
|
||||
op.destHolderId(),
|
||||
op.destTransactionId());
|
||||
const OpDeliverFenceToNonRecycle& op = message.get_OpDeliverFenceToNonRecycle();
|
||||
FenceHandle fence = op.fence();
|
||||
DeliverFenceToNonRecycle(op.TextureId(), fence);
|
||||
break;
|
||||
}
|
||||
case AsyncParentMessageData::TOpNotifyNotUsed: {
|
||||
const OpNotifyNotUsed& op = message.get_OpNotifyNotUsed();
|
||||
NotifyNotUsed(op.TextureId(), op.fwdTransactionId());
|
||||
break;
|
||||
}
|
||||
case AsyncParentMessageData::TOpNotifyNotUsedToNonRecycle: {
|
||||
// Notify ReleaseCompositableRef to a TextureClient that belongs to
|
||||
// LayerTransactionChild. It is used only on gonk to deliver fence to
|
||||
// a TextureClient that does not have TextureFlags::RECYCLE.
|
||||
// In this case, LayerTransactionChild's ipc could not be used to deliver fence.
|
||||
|
||||
const OpNotifyNotUsedToNonRecycle& op = message.get_OpNotifyNotUsedToNonRecycle();
|
||||
NotifyNotUsedToNonRecycle(op.TextureId(), op.fwdTransactionId());
|
||||
break;
|
||||
}
|
||||
case AsyncParentMessageData::TOpReplyRemoveTexture: {
|
||||
const OpReplyRemoveTexture& op = message.get_OpReplyRemoveTexture();
|
||||
|
||||
AsyncTransactionTrackersHolder::TransactionCompleteted(op.holderId(),
|
||||
op.transactionId());
|
||||
MOZ_ASSERT(mTrackersHolder.GetId() == op.holderId());
|
||||
mTrackersHolder.TransactionCompleteted(op.transactionId());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1189,10 +1336,11 @@ ImageBridgeChild::RecvDidComposite(InfallibleTArray<ImageCompositeNotification>&
|
||||
PTextureChild*
|
||||
ImageBridgeChild::CreateTexture(const SurfaceDescriptor& aSharedData,
|
||||
LayersBackend aLayersBackend,
|
||||
TextureFlags aFlags)
|
||||
TextureFlags aFlags,
|
||||
uint64_t aSerial)
|
||||
{
|
||||
MOZ_ASSERT(!mShuttingDown);
|
||||
return SendPTextureConstructor(aSharedData, aLayersBackend, aFlags);
|
||||
return SendPTextureConstructor(aSharedData, aLayersBackend, aFlags, aSerial);
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -1263,15 +1411,14 @@ ImageBridgeChild::RemoveTextureFromCompositableAsync(AsyncTransactionTracker* aA
|
||||
CompositableOperation op(
|
||||
nullptr, aCompositable->GetIPDLActor(),
|
||||
OpRemoveTextureAsync(
|
||||
CompositableClient::GetTrackersHolderId(aCompositable->GetIPDLActor()),
|
||||
mTrackersHolder.GetId(),
|
||||
aAsyncTransactionTracker->GetId(),
|
||||
nullptr, aCompositable->GetIPDLActor(),
|
||||
nullptr, aTexture->GetIPDLActor()));
|
||||
|
||||
mTxn->AddNoSwapEdit(op);
|
||||
// Hold AsyncTransactionTracker until receving reply
|
||||
CompositableClient::HoldUntilComplete(aCompositable->GetIPDLActor(),
|
||||
aAsyncTransactionTracker);
|
||||
mTrackersHolder.HoldUntilComplete(aAsyncTransactionTracker);
|
||||
}
|
||||
|
||||
bool ImageBridgeChild::IsSameProcess() const
|
||||
@ -1279,9 +1426,5 @@ bool ImageBridgeChild::IsSameProcess() const
|
||||
return OtherPid() == base::GetCurrentProcId();
|
||||
}
|
||||
|
||||
void ImageBridgeChild::SendPendingAsyncMessges()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "mozilla/layers/CompositableForwarder.h"
|
||||
#include "mozilla/layers/CompositorTypes.h"
|
||||
#include "mozilla/layers/PImageBridgeChild.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsDebug.h" // for NS_RUNTIMEABORT
|
||||
#include "nsRegion.h" // for nsIntRegion
|
||||
#include "mozilla/gfx/Rect.h"
|
||||
@ -104,7 +105,6 @@ bool InImageBridgeChildThread();
|
||||
*/
|
||||
class ImageBridgeChild final : public PImageBridgeChild
|
||||
, public CompositableForwarder
|
||||
, public AsyncTransactionTrackersHolder
|
||||
, public ShmemAllocator
|
||||
{
|
||||
friend class ImageContainer;
|
||||
@ -200,7 +200,7 @@ public:
|
||||
~ImageBridgeChild();
|
||||
|
||||
virtual PTextureChild*
|
||||
AllocPTextureChild(const SurfaceDescriptor& aSharedData, const LayersBackend& aLayersBackend, const TextureFlags& aFlags) override;
|
||||
AllocPTextureChild(const SurfaceDescriptor& aSharedData, const LayersBackend& aLayersBackend, const TextureFlags& aFlags, const uint64_t& aSerial) override;
|
||||
|
||||
virtual bool
|
||||
DeallocPTextureChild(PTextureChild* actor) override;
|
||||
@ -265,6 +265,30 @@ public:
|
||||
const nsIntRect& aPictureRect) override;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Hold TextureClient ref until end of usage on host side if TextureFlags::RECYCLE is set.
|
||||
* Host side's usage is checked via CompositableRef.
|
||||
*/
|
||||
void HoldUntilCompositableRefReleasedIfNecessary(TextureClient* aClient);
|
||||
|
||||
/**
|
||||
* Notify id of Texture When host side end its use. Transaction id is used to
|
||||
* make sure if there is no newer usage.
|
||||
*/
|
||||
void NotifyNotUsed(uint64_t aTextureId, uint64_t aFwdTransactionId);
|
||||
|
||||
void DeliverFence(uint64_t aTextureId, FenceHandle& aReleaseFenceHandle);
|
||||
|
||||
void HoldUntilFenceHandleDelivery(TextureClient* aClient, uint64_t aTransactionId);
|
||||
|
||||
void DeliverFenceToNonRecycle(uint64_t aTextureId, FenceHandle& aReleaseFenceHandle);
|
||||
|
||||
void NotifyNotUsedToNonRecycle(uint64_t aTextureId, uint64_t aTransactionId);
|
||||
|
||||
void CancelWaitFenceHandle(TextureClient* aClient);
|
||||
|
||||
virtual void CancelWaitForRecycle(uint64_t aTextureId) override;
|
||||
|
||||
virtual bool DestroyInTransaction(PTextureChild* aTexture, bool synchronously) override;
|
||||
virtual bool DestroyInTransaction(PCompositableChild* aCompositable, bool synchronously) override;
|
||||
|
||||
@ -312,11 +336,13 @@ public:
|
||||
|
||||
virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
|
||||
LayersBackend aLayersBackend,
|
||||
TextureFlags aFlags) override;
|
||||
TextureFlags aFlags,
|
||||
uint64_t aSerial) override;
|
||||
|
||||
virtual bool IsSameProcess() const override;
|
||||
|
||||
virtual void SendPendingAsyncMessges() override;
|
||||
virtual void UpdateFwdTransactionId() override { ++mFwdTransactionId; }
|
||||
virtual uint64_t GetFwdTransactionId() override { return mFwdTransactionId; }
|
||||
|
||||
void MarkShutDown();
|
||||
|
||||
@ -331,6 +357,25 @@ protected:
|
||||
CompositableTransaction* mTxn;
|
||||
Atomic<bool> mShuttingDown;
|
||||
static Atomic<bool> sIsShutDown;
|
||||
|
||||
/**
|
||||
* Transaction id of CompositableForwarder.
|
||||
* It is incrementaed by UpdateFwdTransactionId() in each BeginTransaction() call.
|
||||
*/
|
||||
uint64_t mFwdTransactionId;
|
||||
|
||||
/**
|
||||
* Hold TextureClients refs until end of their usages on host side.
|
||||
* It defer calling of TextureClient recycle callback.
|
||||
*/
|
||||
nsDataHashtable<nsUint64HashKey, RefPtr<TextureClient> > mTexturesWaitingRecycled;
|
||||
|
||||
AsyncTransactionTrackersHolder mTrackersHolder;
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
Mutex mWaitingFenceHandleMutex;
|
||||
nsDataHashtable<nsUint64HashKey, RefPtr<TextureClient> > mTexturesWaitingFenceHandle;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
@ -134,7 +134,10 @@ public:
|
||||
explicit AutoImageBridgeParentAsyncMessageSender(ImageBridgeParent* aImageBridge,
|
||||
InfallibleTArray<OpDestroy>* aToDestroy = nullptr)
|
||||
: mImageBridge(aImageBridge)
|
||||
, mToDestroy(aToDestroy) {}
|
||||
, mToDestroy(aToDestroy)
|
||||
{
|
||||
mImageBridge->SetAboutToSendAsyncMessages();
|
||||
}
|
||||
|
||||
~AutoImageBridgeParentAsyncMessageSender()
|
||||
{
|
||||
@ -152,9 +155,11 @@ private:
|
||||
|
||||
bool
|
||||
ImageBridgeParent::RecvUpdate(EditArray&& aEdits, OpDestroyArray&& aToDestroy,
|
||||
const uint64_t& aFwdTransactionId,
|
||||
EditReplyArray* aReply)
|
||||
{
|
||||
AutoImageBridgeParentAsyncMessageSender autoAsyncMessageSender(this, &aToDestroy);
|
||||
UpdateFwdTransactionId(aFwdTransactionId);
|
||||
|
||||
EditReplyVector replyv;
|
||||
for (EditArray::index_type i = 0; i < aEdits.Length(); ++i) {
|
||||
@ -179,10 +184,11 @@ ImageBridgeParent::RecvUpdate(EditArray&& aEdits, OpDestroyArray&& aToDestroy,
|
||||
}
|
||||
|
||||
bool
|
||||
ImageBridgeParent::RecvUpdateNoSwap(EditArray&& aEdits, OpDestroyArray&& aToDestroy)
|
||||
ImageBridgeParent::RecvUpdateNoSwap(EditArray&& aEdits, OpDestroyArray&& aToDestroy,
|
||||
const uint64_t& aFwdTransactionId)
|
||||
{
|
||||
InfallibleTArray<EditReply> noReplies;
|
||||
bool success = RecvUpdate(Move(aEdits), Move(aToDestroy), &noReplies);
|
||||
bool success = RecvUpdate(Move(aEdits), Move(aToDestroy), aFwdTransactionId, &noReplies);
|
||||
MOZ_ASSERT(noReplies.Length() == 0, "RecvUpdateNoSwap requires a sync Update to carry Edits");
|
||||
return success;
|
||||
}
|
||||
@ -251,9 +257,10 @@ bool ImageBridgeParent::DeallocPCompositableParent(PCompositableParent* aActor)
|
||||
PTextureParent*
|
||||
ImageBridgeParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
|
||||
const LayersBackend& aLayersBackend,
|
||||
const TextureFlags& aFlags)
|
||||
const TextureFlags& aFlags,
|
||||
const uint64_t& aSerial)
|
||||
{
|
||||
return TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags);
|
||||
return TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags, aSerial);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -295,12 +302,6 @@ ImageBridgeParent::SendAsyncMessage(const InfallibleTArray<AsyncParentMessageDat
|
||||
mozilla::Unused << SendParentAsyncMessages(aMessage);
|
||||
}
|
||||
|
||||
bool
|
||||
ImageBridgeParent::RecvChildAsyncMessages(InfallibleTArray<AsyncChildMessageData>&& aMessages)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
class ProcessIdComparator
|
||||
{
|
||||
public:
|
||||
@ -335,6 +336,7 @@ ImageBridgeParent::NotifyImageComposites(nsTArray<ImageCompositeNotification>& a
|
||||
notifications.AppendElement(aNotifications[end]);
|
||||
++end;
|
||||
}
|
||||
GetInstance(pid)->SendPendingAsyncMessages();
|
||||
if (!GetInstance(pid)->SendDidComposite(notifications)) {
|
||||
ok = false;
|
||||
}
|
||||
@ -427,80 +429,76 @@ ImageBridgeParent::ReplyRemoveTexture(const OpReplyRemoveTexture& aReply)
|
||||
mPendingAsyncMessage.push_back(aReply);
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
ImageBridgeParent::ReplyRemoveTexture(base::ProcessId aChildProcessId,
|
||||
const OpReplyRemoveTexture& aReply)
|
||||
{
|
||||
ImageBridgeParent* imageBridge = ImageBridgeParent::GetInstance(aChildProcessId);
|
||||
if (!imageBridge) {
|
||||
return;
|
||||
}
|
||||
imageBridge->ReplyRemoveTexture(aReply);
|
||||
}
|
||||
|
||||
void
|
||||
ImageBridgeParent::SendFenceHandleIfPresent(PTextureParent* aTexture)
|
||||
ImageBridgeParent::SendFenceHandleToNonRecycle(PTextureParent* aTexture)
|
||||
{
|
||||
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
|
||||
if (!texture || !texture->NeedsFenceHandle()) {
|
||||
if (!texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(texture->GetFlags() & TextureFlags::RECYCLE) &&
|
||||
!texture->NeedsFenceHandle()) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t textureId = TextureHost::GetTextureSerial(aTexture);
|
||||
|
||||
// Send a ReleaseFence of CompositorOGL.
|
||||
FenceHandle fence = texture->GetCompositorReleaseFence();
|
||||
if (fence.IsValid()) {
|
||||
mPendingAsyncMessage.push_back(OpDeliverFence(aTexture, nullptr,
|
||||
fence));
|
||||
mPendingAsyncMessage.push_back(OpDeliverFenceToNonRecycle(textureId, fence));
|
||||
}
|
||||
|
||||
// Send a ReleaseFence that is set to TextureHost by HwcComposer2D.
|
||||
fence = texture->GetAndResetReleaseFenceHandle();
|
||||
if (fence.IsValid()) {
|
||||
mPendingAsyncMessage.push_back(OpDeliverFence(aTexture, nullptr,
|
||||
fence));
|
||||
mPendingAsyncMessage.push_back(OpDeliverFenceToNonRecycle(textureId, fence));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ImageBridgeParent::AppendDeliverFenceMessage(uint64_t aDestHolderId,
|
||||
uint64_t aTransactionId,
|
||||
PTextureParent* aTexture)
|
||||
ImageBridgeParent::NotifyNotUsedToNonRecycle(PTextureParent* aTexture,
|
||||
uint64_t aTransactionId)
|
||||
{
|
||||
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
|
||||
if (!texture || !texture->NeedsFenceHandle()) {
|
||||
if (!texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Send a ReleaseFence of CompositorOGL.
|
||||
FenceHandle fence = texture->GetCompositorReleaseFence();
|
||||
if (fence.IsValid()) {
|
||||
mPendingAsyncMessage.push_back(OpDeliverFenceToTracker(aDestHolderId,
|
||||
aTransactionId,
|
||||
fence));
|
||||
if (!(texture->GetFlags() & TextureFlags::RECYCLE) &&
|
||||
!texture->NeedsFenceHandle()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Send a ReleaseFence that is set to TextureHost by HwcComposer2D.
|
||||
fence = texture->GetAndResetReleaseFenceHandle();
|
||||
if (fence.IsValid()) {
|
||||
mPendingAsyncMessage.push_back(OpDeliverFenceToTracker(aDestHolderId,
|
||||
aTransactionId,
|
||||
fence));
|
||||
}
|
||||
SendFenceHandleToNonRecycle(aTexture);
|
||||
|
||||
uint64_t textureId = TextureHost::GetTextureSerial(aTexture);
|
||||
mPendingAsyncMessage.push_back(
|
||||
OpNotifyNotUsedToNonRecycle(textureId, aTransactionId));
|
||||
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
ImageBridgeParent::AppendDeliverFenceMessage(base::ProcessId aChildProcessId,
|
||||
uint64_t aDestHolderId,
|
||||
uint64_t aTransactionId,
|
||||
PTextureParent* aTexture)
|
||||
ImageBridgeParent::NotifyNotUsedToNonRecycle(base::ProcessId aChildProcessId,
|
||||
PTextureParent* aTexture,
|
||||
uint64_t aTransactionId)
|
||||
{
|
||||
ImageBridgeParent* imageBridge = ImageBridgeParent::GetInstance(aChildProcessId);
|
||||
if (!imageBridge) {
|
||||
return;
|
||||
}
|
||||
imageBridge->AppendDeliverFenceMessage(aDestHolderId,
|
||||
aTransactionId,
|
||||
aTexture);
|
||||
imageBridge->NotifyNotUsedToNonRecycle(aTexture, aTransactionId);
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
ImageBridgeParent::SetAboutToSendAsyncMessages(base::ProcessId aChildProcessId)
|
||||
{
|
||||
ImageBridgeParent* imageBridge = ImageBridgeParent::GetInstance(aChildProcessId);
|
||||
if (!imageBridge) {
|
||||
return;
|
||||
}
|
||||
imageBridge->SetAboutToSendAsyncMessages();
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
@ -513,5 +511,28 @@ ImageBridgeParent::SendPendingAsyncMessages(base::ProcessId aChildProcessId)
|
||||
imageBridge->SendPendingAsyncMessages();
|
||||
}
|
||||
|
||||
void
|
||||
ImageBridgeParent::NotifyNotUsed(PTextureParent* aTexture, uint64_t aTransactionId)
|
||||
{
|
||||
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
|
||||
if (!texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(texture->GetFlags() & TextureFlags::RECYCLE) &&
|
||||
!texture->NeedsFenceHandle()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SendFenceHandleIfPresent(aTexture);
|
||||
uint64_t textureId = TextureHost::GetTextureSerial(aTexture);
|
||||
mPendingAsyncMessage.push_back(
|
||||
OpNotifyNotUsed(textureId, aTransactionId));
|
||||
|
||||
if (!IsAboutToSendAsyncMessages()) {
|
||||
SendPendingAsyncMessages();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
@ -46,7 +46,6 @@ public:
|
||||
typedef InfallibleTArray<CompositableOperation> EditArray;
|
||||
typedef InfallibleTArray<OpDestroy> OpDestroyArray;
|
||||
typedef InfallibleTArray<EditReply> EditReplyArray;
|
||||
typedef InfallibleTArray<AsyncChildMessageData> AsyncChildMessageArray;
|
||||
|
||||
ImageBridgeParent(MessageLoop* aLoop, Transport* aTransport, ProcessId aChildProcessId);
|
||||
~ImageBridgeParent();
|
||||
@ -59,10 +58,10 @@ public:
|
||||
Create(Transport* aTransport, ProcessId aChildProcessId, ipc::GeckoChildProcessHost* aProcessHost);
|
||||
|
||||
// CompositableParentManager
|
||||
virtual void SendFenceHandleIfPresent(PTextureParent* aTexture) override;
|
||||
|
||||
virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) override;
|
||||
|
||||
virtual void NotifyNotUsed(PTextureParent* aTexture, uint64_t aTransactionId) override;
|
||||
|
||||
virtual base::ProcessId GetChildProcessId() override
|
||||
{
|
||||
return OtherPid();
|
||||
@ -71,8 +70,10 @@ public:
|
||||
// PImageBridge
|
||||
virtual bool RecvImageBridgeThreadId(const PlatformThreadId& aThreadId) override;
|
||||
virtual bool RecvUpdate(EditArray&& aEdits, OpDestroyArray&& aToDestroy,
|
||||
const uint64_t& aFwdTransactionId,
|
||||
EditReplyArray* aReply) override;
|
||||
virtual bool RecvUpdateNoSwap(EditArray&& aEdits, OpDestroyArray&& aToDestroy) override;
|
||||
virtual bool RecvUpdateNoSwap(EditArray&& aEdits, OpDestroyArray&& aToDestroy,
|
||||
const uint64_t& aFwdTransactionId) override;
|
||||
|
||||
PCompositableParent* AllocPCompositableParent(const TextureInfo& aInfo,
|
||||
PImageContainerParent* aImageContainer,
|
||||
@ -81,7 +82,8 @@ public:
|
||||
|
||||
virtual PTextureParent* AllocPTextureParent(const SurfaceDescriptor& aSharedData,
|
||||
const LayersBackend& aLayersBackend,
|
||||
const TextureFlags& aFlags) override;
|
||||
const TextureFlags& aFlags,
|
||||
const uint64_t& aSerial) override;
|
||||
virtual bool DeallocPTextureParent(PTextureParent* actor) override;
|
||||
|
||||
PMediaSystemResourceManagerParent* AllocPMediaSystemResourceManagerParent() override;
|
||||
@ -89,9 +91,6 @@ public:
|
||||
virtual PImageContainerParent* AllocPImageContainerParent() override;
|
||||
virtual bool DeallocPImageContainerParent(PImageContainerParent* actor) override;
|
||||
|
||||
virtual bool
|
||||
RecvChildAsyncMessages(InfallibleTArray<AsyncChildMessageData>&& aMessages) override;
|
||||
|
||||
// Shutdown step 1
|
||||
virtual bool RecvWillClose() override;
|
||||
|
||||
@ -113,17 +112,17 @@ public:
|
||||
|
||||
virtual void ReplyRemoveTexture(const OpReplyRemoveTexture& aReply) override;
|
||||
|
||||
static void ReplyRemoveTexture(base::ProcessId aChildProcessId,
|
||||
const OpReplyRemoveTexture& aReply);
|
||||
void SendFenceHandleToNonRecycle(PTextureParent* aTexture);
|
||||
|
||||
void AppendDeliverFenceMessage(uint64_t aDestHolderId,
|
||||
uint64_t aTransactionId,
|
||||
PTextureParent* aTexture);
|
||||
void NotifyNotUsedToNonRecycle(PTextureParent* aTexture,
|
||||
uint64_t aTransactionId);
|
||||
|
||||
static void AppendDeliverFenceMessage(base::ProcessId aChildProcessId,
|
||||
uint64_t aDestHolderId,
|
||||
uint64_t aTransactionId,
|
||||
PTextureParent* aTexture);
|
||||
static void NotifyNotUsedToNonRecycle(base::ProcessId aChildProcessId,
|
||||
PTextureParent* aTexture,
|
||||
uint64_t aTransactionId);
|
||||
|
||||
using CompositableParentManager::SetAboutToSendAsyncMessages;
|
||||
static void SetAboutToSendAsyncMessages(base::ProcessId aChildProcessId);
|
||||
|
||||
using CompositableParentManager::SendPendingAsyncMessages;
|
||||
static void SendPendingAsyncMessages(base::ProcessId aChildProcessId);
|
||||
|
@ -69,44 +69,10 @@ LayerTransactionChild::DeallocPCompositableChild(PCompositableChild* actor)
|
||||
return CompositableClient::DestroyIPDLActor(actor);
|
||||
}
|
||||
|
||||
bool
|
||||
LayerTransactionChild::RecvParentAsyncMessages(InfallibleTArray<AsyncParentMessageData>&& aMessages)
|
||||
{
|
||||
for (AsyncParentMessageArray::index_type i = 0; i < aMessages.Length(); ++i) {
|
||||
const AsyncParentMessageData& message = aMessages[i];
|
||||
|
||||
switch (message.type()) {
|
||||
case AsyncParentMessageData::TOpDeliverFence: {
|
||||
const OpDeliverFence& op = message.get_OpDeliverFence();
|
||||
FenceHandle fence = op.fence();
|
||||
PTextureChild* child = op.textureChild();
|
||||
|
||||
RefPtr<TextureClient> texture = TextureClient::AsTextureClient(child);
|
||||
if (texture) {
|
||||
texture->SetReleaseFenceHandle(fence);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AsyncParentMessageData::TOpReplyRemoveTexture: {
|
||||
const OpReplyRemoveTexture& op = message.get_OpReplyRemoveTexture();
|
||||
|
||||
AsyncTransactionTrackersHolder::TransactionCompleteted(op.holderId(),
|
||||
op.transactionId());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NS_ERROR("unknown AsyncParentMessageData type");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
LayerTransactionChild::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
mDestroyed = true;
|
||||
DestroyAsyncTransactionTrackersHolder();
|
||||
#ifdef MOZ_B2G
|
||||
// Due to poor lifetime management of gralloc (and possibly shmems) we will
|
||||
// crash at some point in the future when we get destroyed due to abnormal
|
||||
|
@ -26,9 +26,7 @@ namespace layers {
|
||||
class ShadowLayerForwarder;
|
||||
|
||||
class LayerTransactionChild : public PLayerTransactionChild
|
||||
, public AsyncTransactionTrackersHolder
|
||||
{
|
||||
typedef InfallibleTArray<AsyncParentMessageData> AsyncParentMessageArray;
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(LayerTransactionChild)
|
||||
/**
|
||||
@ -65,9 +63,6 @@ protected:
|
||||
virtual PCompositableChild* AllocPCompositableChild(const TextureInfo& aInfo) override;
|
||||
virtual bool DeallocPCompositableChild(PCompositableChild* actor) override;
|
||||
|
||||
virtual bool
|
||||
RecvParentAsyncMessages(InfallibleTArray<AsyncParentMessageData>&& aMessages) override;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) override;
|
||||
|
||||
void AddIPDLReference() {
|
||||
|
@ -184,6 +184,7 @@ LayerTransactionParent::Destroy()
|
||||
bool
|
||||
LayerTransactionParent::RecvUpdateNoSwap(InfallibleTArray<Edit>&& cset,
|
||||
InfallibleTArray<OpDestroy>&& aToDestroy,
|
||||
const uint64_t& aFwdTransactionId,
|
||||
const uint64_t& aTransactionId,
|
||||
const TargetConfig& targetConfig,
|
||||
PluginsArray&& aPlugins,
|
||||
@ -194,7 +195,7 @@ LayerTransactionParent::RecvUpdateNoSwap(InfallibleTArray<Edit>&& cset,
|
||||
const mozilla::TimeStamp& aTransactionStart,
|
||||
const int32_t& aPaintSyncId)
|
||||
{
|
||||
return RecvUpdate(Move(cset), Move(aToDestroy),
|
||||
return RecvUpdate(Move(cset), Move(aToDestroy), aFwdTransactionId,
|
||||
aTransactionId, targetConfig, Move(aPlugins), isFirstPaint,
|
||||
scheduleComposite, paintSequenceNumber, isRepeatTransaction,
|
||||
aTransactionStart, aPaintSyncId, nullptr);
|
||||
@ -207,7 +208,10 @@ public:
|
||||
InfallibleTArray<OpDestroy>* aDestroyActors = nullptr)
|
||||
: mLayerTransaction(aLayerTransaction)
|
||||
, mActorsToDestroy(aDestroyActors)
|
||||
{}
|
||||
{
|
||||
mLayerTransaction->SetAboutToSendAsyncMessages();
|
||||
ImageBridgeParent::SetAboutToSendAsyncMessages(mLayerTransaction->GetChildProcessId());
|
||||
}
|
||||
|
||||
~AutoLayerTransactionParentAsyncMessageSender()
|
||||
{
|
||||
@ -229,6 +233,7 @@ private:
|
||||
bool
|
||||
LayerTransactionParent::RecvUpdate(InfallibleTArray<Edit>&& cset,
|
||||
InfallibleTArray<OpDestroy>&& aToDestroy,
|
||||
const uint64_t& aFwdTransactionId,
|
||||
const uint64_t& aTransactionId,
|
||||
const TargetConfig& targetConfig,
|
||||
PluginsArray&& aPlugins,
|
||||
@ -250,6 +255,8 @@ LayerTransactionParent::RecvUpdate(InfallibleTArray<Edit>&& cset,
|
||||
|
||||
MOZ_LAYERS_LOG(("[ParentSide] received txn with %d edits", cset.Length()));
|
||||
|
||||
UpdateFwdTransactionId(aFwdTransactionId);
|
||||
|
||||
if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
|
||||
for (const auto& op : aToDestroy) {
|
||||
DestroyActor(op);
|
||||
@ -981,57 +988,6 @@ LayerTransactionParent::DeallocPCompositableParent(PCompositableParent* aActor)
|
||||
return CompositableHost::DestroyIPDLActor(aActor);
|
||||
}
|
||||
|
||||
bool
|
||||
LayerTransactionParent::RecvChildAsyncMessages(InfallibleTArray<AsyncChildMessageData>&& aMessages)
|
||||
{
|
||||
AutoLayerTransactionParentAsyncMessageSender autoAsyncMessageSender(this);
|
||||
|
||||
for (AsyncChildMessageArray::index_type i = 0; i < aMessages.Length(); ++i) {
|
||||
const AsyncChildMessageData& message = aMessages[i];
|
||||
|
||||
switch (message.type()) {
|
||||
case AsyncChildMessageData::TCompositableOperation: {
|
||||
|
||||
const CompositableOperation& compositable_op =
|
||||
message.get_CompositableOperation();
|
||||
MOZ_ASSERT(compositable_op.detail().type() ==
|
||||
CompositableOperationDetail::TOpRemoveTextureAsync);
|
||||
|
||||
const OpRemoveTextureAsync& op =
|
||||
compositable_op.detail().get_OpRemoveTextureAsync();
|
||||
|
||||
CompositableHost* compositable = CompositableHost::FromIPDLActor(op.compositableParent());
|
||||
RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent());
|
||||
|
||||
MOZ_ASSERT(tex.get());
|
||||
compositable->RemoveTextureHost(tex);
|
||||
|
||||
MOZ_ASSERT(ImageBridgeParent::GetInstance(GetChildProcessId()));
|
||||
if (ImageBridgeParent::GetInstance(GetChildProcessId())) {
|
||||
// send FenceHandle if present via ImageBridge.
|
||||
ImageBridgeParent::AppendDeliverFenceMessage(
|
||||
GetChildProcessId(),
|
||||
op.holderId(),
|
||||
op.transactionId(),
|
||||
op.textureParent());
|
||||
// Send message back via PImageBridge.
|
||||
ImageBridgeParent::ReplyRemoveTexture(
|
||||
GetChildProcessId(),
|
||||
OpReplyRemoveTexture(op.holderId(),
|
||||
op.transactionId()));
|
||||
} else {
|
||||
NS_ERROR("ImageBridgeParent should exist");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NS_ERROR("unknown AsyncChildMessageData type");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
LayerTransactionParent::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
@ -1074,41 +1030,28 @@ bool LayerTransactionParent::IsSameProcess() const
|
||||
return OtherPid() == base::GetCurrentProcId();
|
||||
}
|
||||
|
||||
void
|
||||
LayerTransactionParent::SendFenceHandleIfPresent(PTextureParent* aTexture)
|
||||
{
|
||||
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
|
||||
if (!texture || !texture->NeedsFenceHandle()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Send a ReleaseFence of CompositorOGL.
|
||||
FenceHandle fence = texture->GetCompositorReleaseFence();
|
||||
if (fence.IsValid()) {
|
||||
mPendingAsyncMessage.push_back(OpDeliverFence(aTexture, nullptr,
|
||||
fence));
|
||||
}
|
||||
|
||||
// Send a ReleaseFence that is set to TextureHost by HwcComposer2D.
|
||||
fence = texture->GetAndResetReleaseFenceHandle();
|
||||
if (fence.IsValid()) {
|
||||
mPendingAsyncMessage.push_back(OpDeliverFence(aTexture, nullptr,
|
||||
fence));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LayerTransactionParent::SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage)
|
||||
{
|
||||
mozilla::Unused << SendParentAsyncMessages(aMessage);
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
||||
}
|
||||
|
||||
void
|
||||
LayerTransactionParent::ReplyRemoveTexture(const OpReplyRemoveTexture& aReply)
|
||||
LayerTransactionParent::SendPendingAsyncMessages()
|
||||
{
|
||||
InfallibleTArray<AsyncParentMessageData> messages;
|
||||
messages.AppendElement(aReply);
|
||||
mozilla::Unused << SendParentAsyncMessages(messages);
|
||||
mShadowLayersManager->AsCompositorBridgeParentIPCAllocator()->SendPendingAsyncMessages();
|
||||
}
|
||||
|
||||
void
|
||||
LayerTransactionParent::SetAboutToSendAsyncMessages()
|
||||
{
|
||||
mShadowLayersManager->AsCompositorBridgeParentIPCAllocator()->SetAboutToSendAsyncMessages();
|
||||
}
|
||||
|
||||
void
|
||||
LayerTransactionParent::NotifyNotUsed(PTextureParent* aTexture, uint64_t aTransactionId)
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
|
@ -42,7 +42,6 @@ class LayerTransactionParent final : public PLayerTransactionParent,
|
||||
typedef InfallibleTArray<Edit> EditArray;
|
||||
typedef InfallibleTArray<OpDestroy> OpDestroyArray;
|
||||
typedef InfallibleTArray<EditReply> EditReplyArray;
|
||||
typedef InfallibleTArray<AsyncChildMessageData> AsyncChildMessageArray;
|
||||
typedef InfallibleTArray<PluginWindowData> PluginsArray;
|
||||
|
||||
public:
|
||||
@ -79,17 +78,19 @@ public:
|
||||
void SetPendingTransactionId(uint64_t aId) { mPendingTransaction = aId; }
|
||||
|
||||
// CompositableParentManager
|
||||
virtual void SendFenceHandleIfPresent(PTextureParent* aTexture) override;
|
||||
|
||||
virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) override;
|
||||
|
||||
virtual void SendPendingAsyncMessages() override;
|
||||
|
||||
virtual void SetAboutToSendAsyncMessages() override;
|
||||
|
||||
virtual void NotifyNotUsed(PTextureParent* aTexture, uint64_t aTransactionId) override;
|
||||
|
||||
virtual base::ProcessId GetChildProcessId() override
|
||||
{
|
||||
return OtherPid();
|
||||
}
|
||||
|
||||
virtual void ReplyRemoveTexture(const OpReplyRemoveTexture& aReply) override;
|
||||
|
||||
void AddPendingCompositorUpdate() {
|
||||
mPendingCompositorUpdates++;
|
||||
}
|
||||
@ -110,6 +111,7 @@ protected:
|
||||
|
||||
virtual bool RecvUpdate(EditArray&& cset,
|
||||
OpDestroyArray&& aToDestroy,
|
||||
const uint64_t& aFwdTransactionId,
|
||||
const uint64_t& aTransactionId,
|
||||
const TargetConfig& targetConfig,
|
||||
PluginsArray&& aPlugins,
|
||||
@ -123,6 +125,7 @@ protected:
|
||||
|
||||
virtual bool RecvUpdateNoSwap(EditArray&& cset,
|
||||
OpDestroyArray&& aToDestroy,
|
||||
const uint64_t& aFwdTransactionId,
|
||||
const uint64_t& aTransactionId,
|
||||
const TargetConfig& targetConfig,
|
||||
PluginsArray&& aPlugins,
|
||||
@ -158,9 +161,6 @@ protected:
|
||||
virtual PCompositableParent* AllocPCompositableParent(const TextureInfo& aInfo) override;
|
||||
virtual bool DeallocPCompositableParent(PCompositableParent* actor) override;
|
||||
|
||||
virtual bool
|
||||
RecvChildAsyncMessages(InfallibleTArray<AsyncChildMessageData>&& aMessages) override;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) override;
|
||||
|
||||
bool Attach(ShadowLayerParent* aLayerParent,
|
||||
|
@ -431,16 +431,25 @@ union MaybeRegion {
|
||||
};
|
||||
|
||||
struct OpDeliverFence {
|
||||
PTexture texture;
|
||||
uint64_t TextureId;
|
||||
FenceHandle fence;
|
||||
};
|
||||
|
||||
struct OpDeliverFenceToTracker {
|
||||
uint64_t destHolderId;
|
||||
uint64_t destTransactionId;
|
||||
struct OpDeliverFenceToNonRecycle {
|
||||
uint64_t TextureId;
|
||||
FenceHandle fence;
|
||||
};
|
||||
|
||||
struct OpNotifyNotUsed {
|
||||
uint64_t TextureId;
|
||||
uint64_t fwdTransactionId;
|
||||
};
|
||||
|
||||
struct OpNotifyNotUsedToNonRecycle {
|
||||
uint64_t TextureId;
|
||||
uint64_t fwdTransactionId;
|
||||
};
|
||||
|
||||
union CompositableOperationDetail {
|
||||
OpPaintTextureRegion;
|
||||
|
||||
@ -521,13 +530,11 @@ union EditReply {
|
||||
|
||||
union AsyncParentMessageData {
|
||||
OpDeliverFence;
|
||||
OpDeliverFenceToTracker;
|
||||
OpDeliverFenceToNonRecycle;
|
||||
OpNotifyNotUsed;
|
||||
OpNotifyNotUsedToNonRecycle;
|
||||
OpReplyRemoveTexture;
|
||||
};
|
||||
|
||||
union AsyncChildMessageData {
|
||||
CompositableOperation;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
@ -100,6 +100,8 @@ child:
|
||||
*/
|
||||
async ClearCachedResources(uint64_t id);
|
||||
|
||||
async ParentAsyncMessages(AsyncParentMessageData[] aMessages);
|
||||
|
||||
parent:
|
||||
/**
|
||||
* Confirmation callback for UpdatePluginConfigurations and HideAllPlugins.
|
||||
@ -192,7 +194,7 @@ parent:
|
||||
ScrollableLayerGuid guid,
|
||||
CSSIntRegion region);
|
||||
|
||||
async PTexture(SurfaceDescriptor aSharedData, LayersBackend aBackend, TextureFlags aTextureFlags, uint64_t id);
|
||||
async PTexture(SurfaceDescriptor aSharedData, LayersBackend aBackend, TextureFlags aTextureFlags, uint64_t id, uint64_t aSerial);
|
||||
|
||||
child:
|
||||
// Send back Compositor Frame Metrics from APZCs so tiled layers can
|
||||
|
@ -42,10 +42,10 @@ child:
|
||||
parent:
|
||||
async ImageBridgeThreadId(PlatformThreadId aTreahdId);
|
||||
|
||||
sync Update(CompositableOperation[] ops, OpDestroy[] toDestroy)
|
||||
sync Update(CompositableOperation[] ops, OpDestroy[] toDestroy, uint64_t fwdTransactionId)
|
||||
returns (EditReply[] reply);
|
||||
|
||||
async UpdateNoSwap(CompositableOperation[] ops, OpDestroy[] toDestroy);
|
||||
async UpdateNoSwap(CompositableOperation[] ops, OpDestroy[] toDestroy, uint64_t fwdTransactionId);
|
||||
|
||||
// First step of the destruction sequence. This puts ImageBridge
|
||||
// in a state in which it can't send asynchronous messages
|
||||
@ -58,11 +58,10 @@ parent:
|
||||
|
||||
sync PCompositable(TextureInfo aInfo,
|
||||
nullable PImageContainer aImageContainer) returns (uint64_t id);
|
||||
async PTexture(SurfaceDescriptor aSharedData, LayersBackend aBackend, TextureFlags aTextureFlags);
|
||||
async PTexture(SurfaceDescriptor aSharedData, LayersBackend aBackend, TextureFlags aTextureFlags, uint64_t aSerial);
|
||||
async PMediaSystemResourceManager();
|
||||
async PImageContainer();
|
||||
|
||||
async ChildAsyncMessages(AsyncChildMessageData[] aMessages);
|
||||
};
|
||||
|
||||
|
||||
|
@ -43,9 +43,6 @@ sync protocol PLayerTransaction {
|
||||
manages PLayer;
|
||||
manages PCompositable;
|
||||
|
||||
child:
|
||||
async ParentAsyncMessages(AsyncParentMessageData[] aMessages);
|
||||
|
||||
parent:
|
||||
async PLayer();
|
||||
async PCompositable(TextureInfo aTextureInfo);
|
||||
@ -53,6 +50,7 @@ parent:
|
||||
// The isFirstPaint flag can be used to indicate that this is the first update
|
||||
// for a particular document.
|
||||
sync Update(Edit[] cset, OpDestroy[] toDestroy,
|
||||
uint64_t fwdTransactionId,
|
||||
uint64_t id, TargetConfig targetConfig,
|
||||
PluginWindowData[] plugins, bool isFirstPaint,
|
||||
bool scheduleComposite, uint32_t paintSequenceNumber,
|
||||
@ -63,6 +61,7 @@ parent:
|
||||
// We don't need to send a sync transaction if
|
||||
// no transaction operate require a swap.
|
||||
async UpdateNoSwap(Edit[] cset, OpDestroy[] toDestroy,
|
||||
uint64_t fwdTransactionId,
|
||||
uint64_t id, TargetConfig targetConfig,
|
||||
PluginWindowData[] plugins, bool isFirstPaint,
|
||||
bool scheduleComposite, uint32_t paintSequenceNumber,
|
||||
@ -117,8 +116,6 @@ parent:
|
||||
// input event.
|
||||
async SetConfirmedTargetAPZC(uint64_t aInputBlockId, ScrollableLayerGuid[] aTargets);
|
||||
|
||||
async ChildAsyncMessages(AsyncChildMessageData[] aMessages);
|
||||
|
||||
async Shutdown();
|
||||
|
||||
sync SyncWithCompositor();
|
||||
|
@ -26,12 +26,7 @@ sync protocol PTexture {
|
||||
child:
|
||||
async __delete__();
|
||||
|
||||
async CompositorRecycle();
|
||||
|
||||
parent:
|
||||
|
||||
async ClientRecycle();
|
||||
|
||||
/**
|
||||
* Asynchronously tell the compositor side to remove the texture.
|
||||
*/
|
||||
|
@ -5,6 +5,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ClientLayerManager.h" // for ClientLayerManager
|
||||
#include "ShadowLayers.h"
|
||||
#include <set> // for _Rb_tree_const_iterator, etc
|
||||
#include <vector> // for vector
|
||||
@ -23,6 +24,7 @@
|
||||
#include "mozilla/layers/CompositableClient.h" // for CompositableClient, etc
|
||||
#include "mozilla/layers/CompositorBridgeChild.h"
|
||||
#include "mozilla/layers/ImageDataSerializer.h"
|
||||
#include "mozilla/layers/ImageBridgeChild.h"
|
||||
#include "mozilla/layers/LayersMessages.h" // for Edit, etc
|
||||
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
|
||||
#include "mozilla/layers/LayersTypes.h" // for MOZ_LAYERS_LOG
|
||||
@ -382,8 +384,9 @@ CompositableForwarder::IdentifyTextureHost(const TextureFactoryIdentifier& aIden
|
||||
mSyncObject = SyncObject::CreateSyncObject(aIdentifier.mSyncHandle);
|
||||
}
|
||||
|
||||
ShadowLayerForwarder::ShadowLayerForwarder()
|
||||
: mMessageLoop(MessageLoop::current())
|
||||
ShadowLayerForwarder::ShadowLayerForwarder(ClientLayerManager* aClientLayerManager)
|
||||
: mClientLayerManager(aClientLayerManager)
|
||||
, mMessageLoop(MessageLoop::current())
|
||||
, mDiagnosticTypes(DiagnosticTypes::NO_DIAGNOSTIC)
|
||||
, mIsFirstPaint(false)
|
||||
, mWindowOverlayChanged(false)
|
||||
@ -417,6 +420,7 @@ ShadowLayerForwarder::BeginTransaction(const gfx::IntRect& aTargetBounds,
|
||||
{
|
||||
MOZ_ASSERT(HasShadowManager(), "no manager to forward to");
|
||||
MOZ_ASSERT(mTxn->Finished(), "uncommitted txn?");
|
||||
UpdateFwdTransactionId();
|
||||
mTxn->Begin(aTargetBounds, aRotation, aOrientation);
|
||||
}
|
||||
|
||||
@ -563,6 +567,24 @@ ShadowLayerForwarder::UseTiledLayerBuffer(CompositableClient* aCompositable,
|
||||
{
|
||||
MOZ_ASSERT(aCompositable && aCompositable->IsConnected());
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// GrallocTextureData alwasys requests fence delivery if ANDROID_VERSION >= 17.
|
||||
const InfallibleTArray<TileDescriptor>& tileDescriptors = aTileLayerDescriptor.tiles();
|
||||
for (size_t i = 0; i < tileDescriptors.Length(); i++) {
|
||||
const TileDescriptor& tileDesc = tileDescriptors[i];
|
||||
if (tileDesc.type() != TileDescriptor::TTexturedTileDescriptor) {
|
||||
continue;
|
||||
}
|
||||
const TexturedTileDescriptor& texturedDesc = tileDesc.get_TexturedTileDescriptor();
|
||||
RefPtr<TextureClient> texture = TextureClient::AsTextureClient(texturedDesc.textureChild());
|
||||
mClientLayerManager->GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(texture);
|
||||
if (texturedDesc.textureOnWhite().type() == MaybeTexture::TPTextureChild) {
|
||||
texture = TextureClient::AsTextureClient(texturedDesc.textureOnWhite().get_PTextureChild());
|
||||
mClientLayerManager->GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(texture);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
mTxn->AddNoSwapPaint(CompositableOperation(nullptr, aCompositable->GetIPDLActor(),
|
||||
OpUseTiledLayerBuffer(aTileLayerDescriptor)));
|
||||
}
|
||||
@ -609,6 +631,7 @@ ShadowLayerForwarder::UseTextures(CompositableClient* aCompositable,
|
||||
// to be synchronous.
|
||||
mTxn->MarkSyncTransaction();
|
||||
}
|
||||
mClientLayerManager->GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(t.mTextureClient);
|
||||
}
|
||||
mTxn->AddEdit(CompositableOperation(nullptr, aCompositable->GetIPDLActor(),
|
||||
OpUseTexture(textures)));
|
||||
@ -633,6 +656,9 @@ ShadowLayerForwarder::UseComponentAlphaTextures(CompositableClient* aCompositabl
|
||||
aTextureOnBlack->SerializeReadLock(readLockB);
|
||||
aTextureOnWhite->SerializeReadLock(readLockW);
|
||||
|
||||
mClientLayerManager->GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(aTextureOnBlack);
|
||||
mClientLayerManager->GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(aTextureOnWhite);
|
||||
|
||||
mTxn->AddEdit(
|
||||
CompositableOperation(
|
||||
nullptr, aCompositable->GetIPDLActor(),
|
||||
@ -712,29 +738,7 @@ ShadowLayerForwarder::RemoveTextureFromCompositableAsync(AsyncTransactionTracker
|
||||
CompositableClient* aCompositable,
|
||||
TextureClient* aTexture)
|
||||
{
|
||||
MOZ_ASSERT(aCompositable);
|
||||
MOZ_ASSERT(aTexture);
|
||||
MOZ_ASSERT(aCompositable->IsConnected());
|
||||
MOZ_ASSERT(aTexture->GetIPDLActor());
|
||||
|
||||
CompositableOperation op(
|
||||
nullptr, aCompositable->GetIPDLActor(),
|
||||
OpRemoveTextureAsync(CompositableClient::GetTrackersHolderId(aCompositable->GetIPDLActor()),
|
||||
aAsyncTransactionTracker->GetId(),
|
||||
nullptr, aCompositable->GetIPDLActor(),
|
||||
nullptr, aTexture->GetIPDLActor()));
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
mPendingAsyncMessages.push_back(op);
|
||||
#else
|
||||
if (mTxn->Opened() && aCompositable->IsConnected()) {
|
||||
mTxn->AddEdit(op);
|
||||
} else {
|
||||
NS_RUNTIMEABORT("not reached");
|
||||
}
|
||||
#endif
|
||||
CompositableClient::HoldUntilComplete(aCompositable->GetIPDLActor(),
|
||||
aAsyncTransactionTracker);
|
||||
NS_RUNTIMEABORT("not reached");
|
||||
}
|
||||
|
||||
bool
|
||||
@ -923,6 +927,7 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies,
|
||||
if (!HasShadowManager() ||
|
||||
!mShadowManager->IPCOpen() ||
|
||||
!mShadowManager->SendUpdate(cset, mTxn->mDestroyedActors,
|
||||
GetFwdTransactionId(),
|
||||
aId, targetConfig, mPluginWindowData,
|
||||
mIsFirstPaint, aScheduleComposite,
|
||||
aPaintSequenceNumber, aIsRepeatTransaction,
|
||||
@ -939,6 +944,7 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies,
|
||||
if (!HasShadowManager() ||
|
||||
!mShadowManager->IPCOpen() ||
|
||||
!mShadowManager->SendUpdateNoSwap(cset, mTxn->mDestroyedActors,
|
||||
GetFwdTransactionId(),
|
||||
aId, targetConfig, mPluginWindowData,
|
||||
mIsFirstPaint, aScheduleComposite,
|
||||
aPaintSequenceNumber, aIsRepeatTransaction,
|
||||
@ -1083,14 +1089,15 @@ void ShadowLayerForwarder::AttachAsyncCompositable(uint64_t aCompositableID,
|
||||
PTextureChild*
|
||||
ShadowLayerForwarder::CreateTexture(const SurfaceDescriptor& aSharedData,
|
||||
LayersBackend aLayersBackend,
|
||||
TextureFlags aFlags)
|
||||
TextureFlags aFlags,
|
||||
uint64_t aSerial)
|
||||
{
|
||||
if (!HasShadowManager() ||
|
||||
!mShadowManager->IPCOpen() ||
|
||||
!mShadowManager->Manager()) {
|
||||
return nullptr;
|
||||
}
|
||||
return mShadowManager->Manager()->SendPTextureConstructor(aSharedData, aLayersBackend, aFlags, mShadowManager->GetId());
|
||||
return mShadowManager->Manager()->SendPTextureConstructor(aSharedData, aLayersBackend, aFlags, mShadowManager->GetId(), aSerial);
|
||||
}
|
||||
|
||||
|
||||
@ -1106,7 +1113,6 @@ void ShadowLayerForwarder::StopReceiveAsyncParentMessge()
|
||||
!mShadowManager->IPCOpen()) {
|
||||
return;
|
||||
}
|
||||
SendPendingAsyncMessges();
|
||||
mShadowManager->SetForwarder(nullptr);
|
||||
}
|
||||
|
||||
@ -1116,7 +1122,6 @@ void ShadowLayerForwarder::ClearCachedResources()
|
||||
!mShadowManager->IPCOpen()) {
|
||||
return;
|
||||
}
|
||||
SendPendingAsyncMessges();
|
||||
mShadowManager->SendClearCachedResources();
|
||||
}
|
||||
|
||||
@ -1129,27 +1134,6 @@ void ShadowLayerForwarder::Composite()
|
||||
mShadowManager->SendForceComposite();
|
||||
}
|
||||
|
||||
void ShadowLayerForwarder::SendPendingAsyncMessges()
|
||||
{
|
||||
if (!HasShadowManager() ||
|
||||
!mShadowManager->IPCOpen()) {
|
||||
mPendingAsyncMessages.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mPendingAsyncMessages.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
InfallibleTArray<AsyncChildMessageData> replies;
|
||||
// Prepare pending messages.
|
||||
for (size_t i = 0; i < mPendingAsyncMessages.size(); i++) {
|
||||
replies.AppendElement(mPendingAsyncMessages[i]);
|
||||
}
|
||||
mPendingAsyncMessages.clear();
|
||||
mShadowManager->SendChildAsyncMessages(replies);
|
||||
}
|
||||
|
||||
bool
|
||||
IsSurfaceDescriptorValid(const SurfaceDescriptor& aSurface)
|
||||
{
|
||||
@ -1287,5 +1271,33 @@ ShadowLayerForwarder::DestroySurfaceDescriptor(SurfaceDescriptor* aSurface)
|
||||
*aSurface = SurfaceDescriptor();
|
||||
}
|
||||
|
||||
void
|
||||
ShadowLayerForwarder::UpdateFwdTransactionId()
|
||||
{
|
||||
GetCompositorBridgeChild()->UpdateFwdTransactionId();
|
||||
}
|
||||
|
||||
uint64_t
|
||||
ShadowLayerForwarder::GetFwdTransactionId()
|
||||
{
|
||||
return GetCompositorBridgeChild()->GetFwdTransactionId();
|
||||
}
|
||||
|
||||
void
|
||||
ShadowLayerForwarder::CancelWaitForRecycle(uint64_t aTextureId)
|
||||
{
|
||||
GetCompositorBridgeChild()->CancelWaitForRecycle(aTextureId);
|
||||
}
|
||||
|
||||
CompositorBridgeChild*
|
||||
ShadowLayerForwarder::GetCompositorBridgeChild()
|
||||
{
|
||||
if (mCompositorBridgeChild) {
|
||||
return mCompositorBridgeChild;
|
||||
}
|
||||
mCompositorBridgeChild = mClientLayerManager->GetCompositorBridgeChild();
|
||||
return mCompositorBridgeChild;
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
@ -27,6 +27,8 @@
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class ClientLayerManager;
|
||||
class CompositorBridgeChild;
|
||||
class EditReply;
|
||||
class FixedSizeSmallShmemSectionAllocator;
|
||||
class ImageContainer;
|
||||
@ -141,7 +143,8 @@ public:
|
||||
|
||||
virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
|
||||
LayersBackend aLayersBackend,
|
||||
TextureFlags aFlags) override;
|
||||
TextureFlags aFlags,
|
||||
uint64_t aSerial) override;
|
||||
|
||||
/**
|
||||
* Adds an edit in the layers transaction in order to attach
|
||||
@ -291,8 +294,6 @@ public:
|
||||
|
||||
void Composite();
|
||||
|
||||
virtual void SendPendingAsyncMessges() override;
|
||||
|
||||
/**
|
||||
* True if this is forwarding to a LayerManagerComposite.
|
||||
*/
|
||||
@ -349,6 +350,8 @@ public:
|
||||
|
||||
virtual MessageLoop* GetMessageLoop() const override { return mMessageLoop; }
|
||||
|
||||
virtual void CancelWaitForRecycle(uint64_t aTextureId) override;
|
||||
|
||||
base::ProcessId GetParentPid() const;
|
||||
|
||||
/**
|
||||
@ -377,11 +380,14 @@ public:
|
||||
|
||||
virtual void DestroySurfaceDescriptor(SurfaceDescriptor* aSurface) override;
|
||||
|
||||
virtual void UpdateFwdTransactionId() override;
|
||||
virtual uint64_t GetFwdTransactionId() override;
|
||||
|
||||
// Returns true if aSurface wraps a Shmem.
|
||||
static bool IsShmem(SurfaceDescriptor* aSurface);
|
||||
|
||||
protected:
|
||||
ShadowLayerForwarder();
|
||||
explicit ShadowLayerForwarder(ClientLayerManager* aClientLayerManager);
|
||||
|
||||
#ifdef DEBUG
|
||||
void CheckSurfaceDescriptor(const SurfaceDescriptor* aDescriptor) const;
|
||||
@ -391,13 +397,16 @@ protected:
|
||||
|
||||
bool InWorkerThread();
|
||||
|
||||
CompositorBridgeChild* GetCompositorBridgeChild();
|
||||
|
||||
RefPtr<LayerTransactionChild> mShadowManager;
|
||||
RefPtr<CompositorBridgeChild> mCompositorBridgeChild;
|
||||
|
||||
private:
|
||||
|
||||
ClientLayerManager* mClientLayerManager;
|
||||
Transaction* mTxn;
|
||||
MessageLoop* mMessageLoop;
|
||||
std::vector<CompositableOperation> mPendingAsyncMessages;
|
||||
DiagnosticTypes mDiagnosticTypes;
|
||||
bool mIsFirstPaint;
|
||||
bool mWindowOverlayChanged;
|
||||
|
@ -14,6 +14,7 @@ class TargetConfig;
|
||||
class LayerTransactionParent;
|
||||
class AsyncCompositionManager;
|
||||
class APZTestData;
|
||||
class CompositorBridgeParentIPCAllocator;
|
||||
|
||||
class ShadowLayersManager
|
||||
{
|
||||
@ -44,6 +45,7 @@ public:
|
||||
virtual void SetConfirmedTargetAPZC(const LayerTransactionParent* aLayerTree,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsTArray<ScrollableLayerGuid>& aTargets) = 0;
|
||||
virtual CompositorBridgeParentIPCAllocator* AsCompositorBridgeParentIPCAllocator() { return nullptr; }
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
@ -157,6 +157,8 @@ CompositorOGL::CreateContext()
|
||||
void
|
||||
CompositorOGL::Destroy()
|
||||
{
|
||||
Compositor::Destroy();
|
||||
|
||||
if (mTexturePool) {
|
||||
mTexturePool->Clear();
|
||||
mTexturePool = nullptr;
|
||||
|
@ -73,6 +73,8 @@ public:
|
||||
|
||||
virtual FenceHandle GetCompositorReleaseFence() override;
|
||||
|
||||
virtual GrallocTextureHostOGL* AsGrallocTextureHostOGL() override { return this; }
|
||||
|
||||
private:
|
||||
void DestroyEGLImage();
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/layers/AsyncTransactionTracker.h" // for AsyncTransactionTracker
|
||||
#include "mozilla/layers/CompositorBridgeChild.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/layers/ImageBridgeChild.h"
|
||||
@ -882,8 +881,6 @@ gfxPlatform::InitLayersIPC()
|
||||
}
|
||||
sLayersIPCIsUp = true;
|
||||
|
||||
AsyncTransactionTrackersHolder::Initialize();
|
||||
|
||||
if (XRE_IsParentProcess())
|
||||
{
|
||||
layers::CompositorThreadHolder::Start();
|
||||
|
@ -432,7 +432,7 @@ status_t GonkBufferQueue::dequeueBuffer(int *outBuf, sp<Fence>* outFence,
|
||||
ST_LOGE("dequeueBuffer: failed to alloc gralloc buffer");
|
||||
return -ENOMEM;
|
||||
}
|
||||
RefPtr<TextureClient> textureClient = new TextureClient(texData, TextureFlags::DEALLOCATE_CLIENT, allocator);
|
||||
RefPtr<TextureClient> textureClient = new TextureClient(texData, TextureFlags::RECYCLE | TextureFlags::DEALLOCATE_CLIENT, allocator);
|
||||
sp<GraphicBuffer> graphicBuffer = texData->GetGraphicBuffer();
|
||||
|
||||
{ // Scope for the lock
|
||||
|
@ -452,7 +452,7 @@ status_t GonkBufferQueue::dequeueBuffer(int *outBuf, sp<Fence>* outFence, bool a
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
RefPtr<TextureClient> textureClient = new TextureClient(texData, TextureFlags::DEALLOCATE_CLIENT, allocator);
|
||||
RefPtr<TextureClient> textureClient = new TextureClient(texData, TextureFlags::RECYCLE | TextureFlags::DEALLOCATE_CLIENT, allocator);
|
||||
|
||||
{ // Scope for the lock
|
||||
Mutex::Autolock lock(mMutex);
|
||||
|
@ -352,7 +352,7 @@ status_t GonkBufferQueueProducer::dequeueBuffer(int *outSlot,
|
||||
return -ENOMEM;
|
||||
}
|
||||
RefPtr<TextureClient> textureClient = TextureClient::CreateWithData(
|
||||
texData, TextureFlags::DEALLOCATE_CLIENT, allocator);
|
||||
texData, TextureFlags::RECYCLE | TextureFlags::DEALLOCATE_CLIENT, allocator);
|
||||
|
||||
sp<GraphicBuffer> graphicBuffer = texData->GetGraphicBuffer();
|
||||
|
||||
|
@ -331,7 +331,7 @@ status_t GonkNativeWindow::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
RefPtr<TextureClient> textureClient = new TextureClient(texData, TextureFlags::DEALLOCATE_CLIENT, allocator);
|
||||
RefPtr<TextureClient> textureClient = new TextureClient(texData, TextureFlags::RECYCLE | TextureFlags::DEALLOCATE_CLIENT, allocator);
|
||||
|
||||
{ // Scope for the lock
|
||||
Mutex::Autolock lock(mMutex);
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
#include "mozilla/layers/ImageBridgeChild.h"
|
||||
#include "mozilla/layers/CompositorBridgeParent.h"
|
||||
#include "mozilla/layers/AsyncTransactionTracker.h"
|
||||
#include "mozilla/layers/SharedBufferManagerChild.h"
|
||||
|
||||
#include "prlink.h"
|
||||
@ -966,8 +965,6 @@ ShutdownXPCOM(nsIServiceManager* aServMgr)
|
||||
|
||||
nsCycleCollector_shutdown();
|
||||
|
||||
layers::AsyncTransactionTrackersHolder::Finalize();
|
||||
|
||||
PROFILER_MARKER("Shutdown xpcom");
|
||||
// If we are doing any shutdown checks, poison writes.
|
||||
if (gShutdownChecks != SCM_NOTHING) {
|
||||
|
Loading…
Reference in New Issue
Block a user