diff options
Diffstat (limited to 'gfx/layers/client/TextureClientPool.h')
-rw-r--r-- | gfx/layers/client/TextureClientPool.h | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/gfx/layers/client/TextureClientPool.h b/gfx/layers/client/TextureClientPool.h new file mode 100644 index 0000000000..d557ca9a03 --- /dev/null +++ b/gfx/layers/client/TextureClientPool.h @@ -0,0 +1,175 @@ +/* -*- 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/. */ + +#ifndef MOZILLA_GFX_TEXTURECLIENTPOOL_H +#define MOZILLA_GFX_TEXTURECLIENTPOOL_H + +#include "mozilla/gfx/Types.h" +#include "mozilla/gfx/Point.h" +#include "mozilla/RefPtr.h" +#include "mozilla/layers/KnowsCompositor.h" +#include "TextureClient.h" +#include "nsITimer.h" +#include <stack> +#include <list> + +namespace mozilla { +namespace layers { + +class ISurfaceAllocator; +class TextureForwarder; +class TextureReadLock; + +class TextureClientAllocator { + protected: + virtual ~TextureClientAllocator() = default; + + public: + NS_INLINE_DECL_REFCOUNTING(TextureClientAllocator) + + virtual already_AddRefed<TextureClient> GetTextureClient() = 0; + + /** + * Return a TextureClient that is not yet ready to be reused, but will be + * imminently. + */ + virtual void ReturnTextureClientDeferred(TextureClient* aClient) = 0; + + virtual void ReportClientLost() = 0; +}; + +class TextureClientPool final : public TextureClientAllocator { + virtual ~TextureClientPool(); + + public: + 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); + + /** + * Gets an allocated TextureClient of size and format that are determined + * by the initialisation parameters given to the pool. This will either be + * a cached client that was returned to the pool, or a newly allocated + * client if one isn't available. + * + * All clients retrieved by this method should be returned using the return + * functions, or reported lost so that the pool can manage its size correctly. + */ + already_AddRefed<TextureClient> GetTextureClient() override; + + /** + * Return a TextureClient that is no longer being used and is ready for + * immediate re-use or destruction. + */ + void ReturnTextureClient(TextureClient* aClient); + + /** + * Return a TextureClient that is not yet ready to be reused, but will be + * imminently. + */ + void ReturnTextureClientDeferred(TextureClient* aClient) override; + + /** + * Return any clients to the pool that were previously returned in + * ReturnTextureClientDeferred. + */ + void ReturnDeferredClients(); + + /** + * Attempt to shrink the pool so that there are no more than + * mInitialPoolSize outstanding. + */ + void ShrinkToMaximumSize(); + + /** + * Report that a client retrieved via GetTextureClient() has become + * unusable, so that it will no longer be tracked. + */ + void ReportClientLost() override; + + /** + * Calling this will cause the pool to attempt to relinquish any unused + * clients. + */ + void Clear(); + + LayersBackend GetBackend() const { + return mKnowsCompositor->GetCompositorBackendType(); + } + int32_t GetMaxTextureSize() const { + return mKnowsCompositor->GetMaxTextureSize(); + } + gfx::SurfaceFormat GetFormat() { return mFormat; } + TextureFlags GetFlags() const { return mFlags; } + + /** + * Clear the pool and put it in a state where it won't recycle any new + * texture. + */ + void Destroy(); + + private: + void ReturnUnlockedClients(); + + /// Allocate a single TextureClient to be returned from the pool. + void AllocateTextureClient(); + + /// Reset and/or initialise timers for shrinking/clearing the pool. + void ResetTimers(); + + /// KnowsCompositor passed to the TextureClient for buffer creation. + RefPtr<KnowsCompositor> mKnowsCompositor; + + /// Format is passed to the TextureClient for buffer creation. + gfx::SurfaceFormat mFormat; + + /// The width and height of the tiles to be used. + gfx::IntSize mSize; + + /// Flags passed to the TextureClient for buffer creation. + const TextureFlags mFlags; + + /// How long to wait after a TextureClient is returned before trying + /// to shrink the pool to its maximum size of mPoolUnusedSize. + uint32_t mShrinkTimeoutMsec; + + /// How long to wait after a TextureClient is returned before trying + /// to clear the pool. + uint32_t mClearTimeoutMsec; + + // The initial number of unused texture clients to seed the pool with + // on construction + uint32_t mInitialPoolSize; + + // How many unused texture clients to try and keep around if we go over + // the initial allocation + uint32_t mPoolUnusedSize; + + /// This is a total number of clients in the wild and in the stack of + /// deferred clients (see below). So, the total number of clients in + /// existence is always mOutstandingClients + the size of mTextureClients. + uint32_t mOutstandingClients; + + std::stack<RefPtr<TextureClient>> mTextureClients; + + std::list<RefPtr<TextureClient>> mTextureClientsDeferred; + RefPtr<nsITimer> mShrinkTimer; + RefPtr<nsITimer> mClearTimer; + // This mSurfaceAllocator owns us, so no need to hold a ref to it + TextureForwarder* mSurfaceAllocator; + + // Keep track of whether this pool has been destroyed or not. If it has, + // we won't accept returns of TextureClients anymore, and the refcounting + // should take care of their destruction. + bool mDestroyed; +}; + +} // namespace layers +} // namespace mozilla + +#endif /* MOZILLA_GFX_TEXTURECLIENTPOOL_H */ |