// dispatched function static void ImageBridgeShutdownStep1(ReentrantMonitor *aBarrier, bool *aDone) { ReentrantMonitorAutoEnter autoMon(*aBarrier); MOZ_ASSERT(InImageBridgeChildThread(), "Should be in ImageBridgeChild thread."); MediaSystemResourceManager::Shutdown(); if (sImageBridgeChildSingleton) { // Force all managed protocols to shut themselves down cleanly InfallibleTArray<PCompositableChild*> compositables; sImageBridgeChildSingleton->ManagedPCompositableChild(compositables); for (int i = compositables.Length() - 1; i >= 0; --i) { CompositableClient::FromIPDLActor(compositables[i])->Destroy(); } InfallibleTArray<PTextureChild*> textures; sImageBridgeChildSingleton->ManagedPTextureChild(textures); for (int i = textures.Length() - 1; i >= 0; --i) { TextureClient* client = TextureClient::AsTextureClient(textures[i]); if (client) { client->ForceRemove(); } } sImageBridgeChildSingleton->SendWillStop(); sImageBridgeChildSingleton->MarkShutDown(); // From now on, no message can be sent through the image bridge from the // client side except the final Stop message. } *aDone = true; aBarrier->NotifyAll(); }
void LayerTransactionChild::Destroy() { if (!IPCOpen()) { return; } // mDestroyed is used to prevent calling Send__delete__() twice. // When this function is called from CompositorChild::Destroy(), // under Send__delete__() call, this function is called from // ShadowLayerForwarder's destructor. // When it happens, IPCOpen() is still true. // See bug 1004191. mDestroyed = true; MOZ_ASSERT(0 == ManagedPLayerChild().Count(), "layers should have been cleaned up by now"); const ManagedContainer<PTextureChild>& textures = ManagedPTextureChild(); for (auto iter = textures.ConstIter(); !iter.Done(); iter.Next()) { TextureClient* texture = TextureClient::AsTextureClient(iter.Get()->GetKey()); if (texture) { texture->Destroy(); } } SendShutdown(); }
void LayerTransactionChild::Destroy() { if (!IPCOpen()) { return; } // mDestroyed is used to prevent calling Send__delete__() twice. // When this function is called from CompositorChild::Destroy(), // under Send__delete__() call, this function is called from // ShadowLayerForwarder's destructor. // When it happens, IPCOpen() is still true. // See bug 1004191. mDestroyed = true; MOZ_ASSERT(0 == ManagedPLayerChild().Length(), "layers should have been cleaned up by now"); for (size_t i = 0; i < ManagedPTextureChild().Length(); ++i) { TextureClient* texture = TextureClient::AsTextureClient(ManagedPTextureChild()[i]); if (texture) { texture->ForceRemove(); } } SendShutdown(); }
TextureClient* PersistentBufferProviderShared::GetTextureClient() { // Can't access the front buffer while drawing. MOZ_ASSERT(!mDrawTarget); TextureClient* texture = GetTexture(mFront); if (texture) { texture->EnableReadLock(); } else { gfxCriticalNote << "PersistentBufferProviderShared: front buffer unavailable"; } return texture; }
void PersistentBufferProviderShared::Destroy() { mSnapshot = nullptr; mDrawTarget = nullptr; for (uint32_t i = 0; i < mTextures.length(); ++i) { TextureClient* texture = mTextures[i]; if (texture && texture->IsLocked()) { MOZ_ASSERT(false); texture->Unlock(); } } mTextures.clear(); }
bool PersistentBufferProviderShared::ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) { RefPtr<gfx::DrawTarget> dt(aDT); MOZ_ASSERT(mDrawTarget == dt); // Can't change the current front buffer while its snapshot is borrowed! MOZ_ASSERT(!mSnapshot); mDrawTarget = nullptr; dt = nullptr; TextureClient* back = GetTexture(mBack); MOZ_ASSERT(back); if (back) { back->Unlock(); mFront = mBack; } return !!back; }
void ClientLayerManager::ReportClientLost(TextureClient& aClient) { GetTexturePool(aClient.GetFormat())->ReportClientLost(); }
void ClientLayerManager::ReturnTextureClient(TextureClient& aClient) { GetTexturePool(aClient.GetFormat())->ReturnTextureClient(&aClient); }
void ClientLayerManager::ReturnTextureClientDeferred(TextureClient& aClient) { GetTexturePool(aClient.GetFormat(), aClient.GetFlags())->ReturnTextureClientDeferred(&aClient); }
already_AddRefed<gfx::DrawTarget> PersistentBufferProviderShared::BorrowDrawTarget(const gfx::IntRect& aPersistedRect) { if (!mFwd->GetTextureForwarder()->IPCOpen()) { return nullptr; } MOZ_ASSERT(!mSnapshot); if (IsActivityTracked()) { mFwd->GetActiveResourceTracker().MarkUsed(this); } else { mFwd->GetActiveResourceTracker().AddObject(this); } if (mDrawTarget) { RefPtr<gfx::DrawTarget> dt(mDrawTarget); return dt.forget(); } mFront = Nothing(); auto previousBackBuffer = mBack; TextureClient* tex = GetTexture(mBack); // First try to reuse the current back buffer. If we can do that it means // we can skip copying its content to the new back buffer. if (tex && tex->IsReadLocked()) { // The back buffer is currently used by the compositor, we can't draw // into it. tex = nullptr; } if (!tex) { // Try to grab an already allocated texture if any is available. for (uint32_t i = 0; i < mTextures.length(); ++i) { if (!mTextures[i]->IsReadLocked()) { mBack = Some(i); tex = mTextures[i]; break; } } } if (!tex) { // We have to allocate a new texture. if (mTextures.length() >= 4) { // We should never need to buffer that many textures, something's wrong. MOZ_ASSERT(false); // In theory we throttle the main thread when the compositor can't keep up, // so we shoud never get in a situation where we sent 4 textures to the // compositor and the latter as not released any of them. // This seems to happen, however, in some edge cases such as just after a // device reset (cf. Bug 1291163). // It would be pretty bad to keep piling textures up at this point so we // call NotifyInactive to remove some of our textures. NotifyInactive(); // Give up now. The caller can fall-back to a non-shared buffer provider. return nullptr; } RefPtr<TextureClient> newTexture = TextureClient::CreateForDrawing( mFwd, mFormat, mSize, BackendSelector::Canvas, TextureFlags::DEFAULT, TextureAllocationFlags::ALLOC_DEFAULT ); MOZ_ASSERT(newTexture); if (newTexture) { if (mTextures.append(newTexture)) { tex = newTexture; mBack = Some<uint32_t>(mTextures.length() - 1); } } } if (!tex || !tex->Lock(OpenMode::OPEN_READ_WRITE)) { return nullptr; } if (mBack != previousBackBuffer && !aPersistedRect.IsEmpty()) { TextureClient* previous = GetTexture(previousBackBuffer); if (previous && previous->Lock(OpenMode::OPEN_READ)) { DebugOnly<bool> success = previous->CopyToTextureClient(tex, &aPersistedRect, nullptr); MOZ_ASSERT(success); previous->Unlock(); } } mDrawTarget = tex->BorrowDrawTarget(); RefPtr<gfx::DrawTarget> dt(mDrawTarget); return dt.forget(); }