diff options
Diffstat (limited to '')
-rw-r--r-- | gfx/layers/client/TextureClientPool.cpp | 307 |
1 files changed, 0 insertions, 307 deletions
diff --git a/gfx/layers/client/TextureClientPool.cpp b/gfx/layers/client/TextureClientPool.cpp deleted file mode 100644 index 3eb0c908b6..0000000000 --- a/gfx/layers/client/TextureClientPool.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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 "TextureClientPool.h" -#include "CompositableClient.h" -#include "mozilla/layers/CompositableForwarder.h" -#include "mozilla/layers/TextureForwarder.h" -#include "mozilla/StaticPrefs_layers.h" - -#include "nsComponentManagerUtils.h" - -#define TCP_LOG(...) -// #define TCP_LOG(...) printf_stderr(__VA_ARGS__); - -namespace mozilla { -namespace layers { - -// We want to shrink to our maximum size of N unused tiles -// after a timeout to allow for short-term budget requirements -static void ShrinkCallback(nsITimer* aTimer, void* aClosure) { - static_cast<TextureClientPool*>(aClosure)->ShrinkToMaximumSize(); -} - -// After a certain amount of inactivity, let's clear the pool so that -// we don't hold onto tiles needlessly. In general, allocations are -// cheap enough that re-allocating isn't an issue unless we're allocating -// at an inopportune time (e.g. mid-animation). -static void ClearCallback(nsITimer* aTimer, void* aClosure) { - static_cast<TextureClientPool*>(aClosure)->Clear(); -} - -TextureClientPool::TextureClientPool( - KnowsCompositor* aKnowsCompositor, gfx::SurfaceFormat aFormat, - gfx::IntSize aSize, TextureFlags aFlags, uint32_t aShrinkTimeoutMsec, - uint32_t aClearTimeoutMsec, uint32_t aInitialPoolSize, - uint32_t aPoolUnusedSize, TextureForwarder* aAllocator) - : mKnowsCompositor(aKnowsCompositor), - mFormat(aFormat), - mSize(aSize), - mFlags(aFlags), - mShrinkTimeoutMsec(aShrinkTimeoutMsec), - mClearTimeoutMsec(aClearTimeoutMsec), - mInitialPoolSize(aInitialPoolSize), - mPoolUnusedSize(aPoolUnusedSize), - mOutstandingClients(0), - mSurfaceAllocator(aAllocator), - mDestroyed(false) { - TCP_LOG("TexturePool %p created with maximum unused texture clients %u\n", - this, mInitialPoolSize); - mShrinkTimer = NS_NewTimer(); - mClearTimer = NS_NewTimer(); - if (aFormat == gfx::SurfaceFormat::UNKNOWN) { - gfxWarning() << "Creating texture pool for SurfaceFormat::UNKNOWN format"; - } -} - -TextureClientPool::~TextureClientPool() { - mShrinkTimer->Cancel(); - mClearTimer->Cancel(); -} - -#ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL -static bool TestClientPool(const char* what, TextureClient* aClient, - TextureClientPool* aPool) { - if (!aClient || !aPool) { - return false; - } - - TextureClientPool* actual = aClient->mPoolTracker; - bool ok = (actual == aPool); - if (ok) { - ok = (aClient->GetFormat() == aPool->GetFormat()); - } - - if (!ok) { - if (actual) { - gfxCriticalError() << "Pool error(" << what << "): " << aPool << "-" - << aPool->GetFormat() << ", " << actual << "-" - << actual->GetFormat() << ", " << aClient->GetFormat(); - MOZ_CRASH("GFX: Crashing with actual"); - } else { - gfxCriticalError() << "Pool error(" << what << "): " << aPool << "-" - << aPool->GetFormat() << ", nullptr, " - << aClient->GetFormat(); - MOZ_CRASH("GFX: Crashing without actual"); - } - } - return ok; -} -#endif - -already_AddRefed<TextureClient> TextureClientPool::GetTextureClient() { - // Try to fetch a client from the pool - RefPtr<TextureClient> textureClient; - - // We initially allocate mInitialPoolSize for our pool. If we run - // out of TextureClients, we allocate additional TextureClients to try and - // keep around mPoolUnusedSize - if (mTextureClients.empty()) { - AllocateTextureClient(); - } - - if (mTextureClients.empty()) { - // All our allocations failed, return nullptr - return nullptr; - } - - mOutstandingClients++; - textureClient = mTextureClients.top(); - mTextureClients.pop(); -#ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL - if (textureClient) { - textureClient->mPoolTracker = this; - } - DebugOnly<bool> ok = TestClientPool("fetch", textureClient, this); - MOZ_ASSERT(ok); -#endif - TCP_LOG("TexturePool %p giving %p from pool; size %u outstanding %u\n", this, - textureClient.get(), mTextureClients.size(), mOutstandingClients); - - return textureClient.forget(); -} - -void TextureClientPool::AllocateTextureClient() { - TCP_LOG("TexturePool %p allocating TextureClient, outstanding %u\n", this, - mOutstandingClients); - - TextureAllocationFlags allocFlags = ALLOC_DEFAULT; - - RefPtr<TextureClient> newClient; - if (StaticPrefs::layers_force_shmem_tiles_AtStartup()) { - // gfx::BackendType::NONE means use the content backend - newClient = TextureClient::CreateForRawBufferAccess( - mSurfaceAllocator, mFormat, mSize, gfx::BackendType::NONE, GetBackend(), - mFlags, allocFlags); - } else { - newClient = TextureClient::CreateForDrawing( - mSurfaceAllocator, mFormat, mSize, mKnowsCompositor, - BackendSelector::Content, mFlags, allocFlags); - } - - if (newClient) { - mTextureClients.push(newClient); - } -} - -void TextureClientPool::ResetTimers() { - // Shrink down if we're beyond our maximum size - if (mShrinkTimeoutMsec && - mTextureClients.size() + mTextureClientsDeferred.size() > - mPoolUnusedSize) { - TCP_LOG("TexturePool %p scheduling a shrink-to-max-size\n", this); - mShrinkTimer->InitWithNamedFuncCallback( - ShrinkCallback, this, mShrinkTimeoutMsec, nsITimer::TYPE_ONE_SHOT, - "layers::TextureClientPool::ResetTimers"); - } - - // Clear pool after a period of inactivity to reduce memory consumption - if (mClearTimeoutMsec) { - TCP_LOG("TexturePool %p scheduling a clear\n", this); - mClearTimer->InitWithNamedFuncCallback( - ClearCallback, this, mClearTimeoutMsec, nsITimer::TYPE_ONE_SHOT, - "layers::TextureClientPool::ResetTimers"); - } -} - -void TextureClientPool::ReturnTextureClient(TextureClient* aClient) { - if (!aClient || mDestroyed) { - return; - } -#ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL - DebugOnly<bool> ok = TestClientPool("return", aClient, this); - MOZ_ASSERT(ok); -#endif - // Add the client to the pool: - MOZ_ASSERT(mOutstandingClients > mTextureClientsDeferred.size()); - mOutstandingClients--; - mTextureClients.push(aClient); - TCP_LOG("TexturePool %p had client %p returned; size %u outstanding %u\n", - this, aClient, mTextureClients.size(), mOutstandingClients); - - ResetTimers(); -} - -void TextureClientPool::ReturnTextureClientDeferred(TextureClient* aClient) { - if (!aClient || mDestroyed) { - return; - } - MOZ_ASSERT(aClient->HasReadLock()); -#ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL - DebugOnly<bool> ok = TestClientPool("defer", aClient, this); - MOZ_ASSERT(ok); -#endif - mTextureClientsDeferred.push_back(aClient); - TCP_LOG( - "TexturePool %p had client %p defer-returned, size %u outstanding %u\n", - this, aClient, mTextureClientsDeferred.size(), mOutstandingClients); - - ResetTimers(); -} - -void TextureClientPool::ShrinkToMaximumSize() { - // We're over our desired maximum size, immediately shrink down to the - // maximum. - // - // We cull from the deferred TextureClients first, as we can't reuse those - // until they get returned. - uint32_t totalUnusedTextureClients = - mTextureClients.size() + mTextureClientsDeferred.size(); - - // If we have > mInitialPoolSize outstanding, then we want to keep around - // mPoolUnusedSize at a maximum. If we have fewer than mInitialPoolSize - // outstanding, then keep around the entire initial pool size. - uint32_t targetUnusedClients; - if (mOutstandingClients > mInitialPoolSize) { - targetUnusedClients = mPoolUnusedSize; - } else { - targetUnusedClients = mInitialPoolSize; - } - - TCP_LOG( - "TexturePool %p shrinking to maximum unused size %u; current pool size " - "%u; total outstanding %u\n", - this, targetUnusedClients, totalUnusedTextureClients, - mOutstandingClients); - - while (totalUnusedTextureClients > targetUnusedClients) { - if (!mTextureClientsDeferred.empty()) { - mOutstandingClients--; - TCP_LOG("TexturePool %p dropped deferred client %p; %u remaining\n", this, - mTextureClientsDeferred.front().get(), - mTextureClientsDeferred.size() - 1); - mTextureClientsDeferred.pop_front(); - } else { - TCP_LOG("TexturePool %p dropped non-deferred client %p; %u remaining\n", - this, mTextureClients.top().get(), mTextureClients.size() - 1); - mTextureClients.pop(); - } - totalUnusedTextureClients--; - } -} - -void TextureClientPool::ReturnDeferredClients() { - if (mTextureClientsDeferred.empty()) { - return; - } - - TCP_LOG("TexturePool %p returning %u deferred clients to pool\n", this, - mTextureClientsDeferred.size()); - - ReturnUnlockedClients(); - ShrinkToMaximumSize(); -} - -void TextureClientPool::ReturnUnlockedClients() { - for (auto it = mTextureClientsDeferred.begin(); - it != mTextureClientsDeferred.end();) { - MOZ_ASSERT((*it)->GetNonBlockingReadLockCount() >= 1); - // Last count is held by the lock itself. - if (!(*it)->IsReadLocked()) { - mTextureClients.push(*it); - it = mTextureClientsDeferred.erase(it); - - MOZ_ASSERT(mOutstandingClients > 0); - mOutstandingClients--; - } else { - it++; - } - } -} - -void TextureClientPool::ReportClientLost() { - MOZ_ASSERT(mOutstandingClients > mTextureClientsDeferred.size()); - mOutstandingClients--; - TCP_LOG("TexturePool %p getting report client lost; down to %u outstanding\n", - this, mOutstandingClients); -} - -void TextureClientPool::Clear() { - TCP_LOG("TexturePool %p getting cleared\n", this); - while (!mTextureClients.empty()) { - TCP_LOG("TexturePool %p releasing client %p\n", this, - mTextureClients.top().get()); - mTextureClients.pop(); - } - while (!mTextureClientsDeferred.empty()) { - MOZ_ASSERT(mOutstandingClients > 0); - mOutstandingClients--; - TCP_LOG("TexturePool %p releasing deferred client %p\n", this, - mTextureClientsDeferred.front().get()); - mTextureClientsDeferred.pop_front(); - } -} - -void TextureClientPool::Destroy() { - Clear(); - mDestroyed = true; - mInitialPoolSize = 0; - mPoolUnusedSize = 0; - mKnowsCompositor = nullptr; -} - -} // namespace layers -} // namespace mozilla |