diff options
Diffstat (limited to 'gfx/layers/client/TextureClientPool.h')
-rw-r--r-- | gfx/layers/client/TextureClientPool.h | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/gfx/layers/client/TextureClientPool.h b/gfx/layers/client/TextureClientPool.h new file mode 100644 index 0000000000..642c14bf53 --- /dev/null +++ b/gfx/layers/client/TextureClientPool.h @@ -0,0 +1,180 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- +* 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 "TextureClient.h" +#include "nsITimer.h" +#include <stack> +#include <list> + +namespace mozilla { +namespace layers { + +class ISurfaceAllocator; +class TextureForwarder; +class TextureReadLock; + +class TextureClientAllocator +{ +protected: + virtual ~TextureClientAllocator() {} +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 +{ + ~TextureClientPool(); + +public: + TextureClientPool(LayersBackend aBackend, + int32_t aMaxTextureSize, + 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. + */ + virtual void ReportClientLost() override; + + /** + * Calling this will cause the pool to attempt to relinquish any unused + * clients. + */ + void Clear(); + + LayersBackend GetBackend() const { return mBackend; } + int32_t GetMaxTextureSize() const { return mMaxTextureSize; } + 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(); + + /// Backend passed to the TextureClient for buffer creation. + LayersBackend mBackend; + + // Max texture size passed to the TextureClient for buffer creation. + int32_t mMaxTextureSize; + + /// 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; + + // On b2g gonk, std::queue might be a better choice. + // On ICS, fence wait happens implicitly before drawing. + // Since JB, fence wait happens explicitly when fetching a client from the pool. + 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 */ |